Thêm cột mới vào DataFrame hiện có trong gấu trúc Python


979

Tôi có DataFrame được lập chỉ mục sau với các cột và hàng không được đặt tên liên tục:

          a         b         c         d
2  0.671399  0.101208 -0.181532  0.241273
3  0.446172 -0.243316  0.051767  1.577318
5  0.614758  0.075793 -0.451460 -0.012493

Tôi muốn thêm một cột mới 'e', vào khung dữ liệu hiện có và không muốn thay đổi bất cứ điều gì trong khung dữ liệu (nghĩa là cột mới luôn có cùng độ dài với Khung dữ liệu).

0   -0.335485
1   -1.166658
2   -0.385571
dtype: float64

Làm thế nào tôi có thể thêm cột evào ví dụ trên?

Câu trả lời:


1043

Sử dụng các chỉ mục df1 ban đầu để tạo chuỗi:

df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)

Chỉnh sửa 2015
Một số báo cáo nhận được SettingWithCopyWarningvới mã này.
Tuy nhiên, mã vẫn chạy hoàn hảo với phiên bản gấu trúc hiện tại 0.16.1.

>>> sLength = len(df1['a'])
>>> df1
          a         b         c         d
6 -0.269221 -0.026476  0.997517  1.294385
8  0.917438  0.847941  0.034235 -0.448948

>>> df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
          a         b         c         d         e
6 -0.269221 -0.026476  0.997517  1.294385  1.757167
8  0.917438  0.847941  0.034235 -0.448948  2.228131

>>> p.version.short_version
'0.16.1'

Các SettingWithCopyWarningmục tiêu để thông báo cho một nhiệm vụ có thể không hợp lệ trên một bản sao của Dataframe. Điều đó không nhất thiết nói rằng bạn đã làm sai (nó có thể kích hoạt dương tính giả) nhưng từ 0.13.0 nó cho bạn biết có nhiều phương pháp phù hợp hơn cho cùng một mục đích. Sau đó, nếu bạn nhận được cảnh báo, chỉ cần làm theo lời khuyên của nó: Hãy thử sử dụng .loc [row_index, col_indexer] = value thay thế

>>> df1.loc[:,'f'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
          a         b         c         d         e         f
6 -0.269221 -0.026476  0.997517  1.294385  1.757167 -0.050927
8  0.917438  0.847941  0.034235 -0.448948  2.228131  0.006109
>>> 

Trên thực tế, đây hiện là phương pháp hiệu quả hơn như được mô tả trong tài liệu về gấu trúc


Chỉnh sửa 2017

Như đã nêu trong các nhận xét và bởi @Alexander, hiện là phương pháp tốt nhất để thêm các giá trị của Sê-ri dưới dạng một cột mới của DataFrame có thể được sử dụng assign:

df1 = df1.assign(e=pd.Series(np.random.randn(sLength)).values)

24
nếu bạn cần thêm cột sử dụng DataFrame.insert: df1.insert (0, 'A', Sê-ri (np.random.randn (sLpm), index = df1.index))
lowTech

29
Từ phiên bản Pandas 0.12 trở đi, tôi tin rằng cú pháp này không tối ưu và đưa ra cảnh báo:SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead
Zhubarb

6
Theo dõi .loc như cảnh báo SettingsWithCopy bằng cách nào đó dẫn đến cảnh báo nhiều hơn: ... self.obj [item_labels [indexer [info_axis]]] = value
seongjoo

12
@toto_tico Bạn có thể giải nén một kwargstừ điển, như vậy:df1 = df1.assign(**{'e': p.Series(np.random.randn(sLength)).values})
TC Proctor

23
Thay vì nói "hiện tại" hoặc năm tham chiếu, vui lòng tham khảo số phiên bản gấu trúc, ví dụ: "trong khoảng từ 0,14-0,16 do X, trong 0,17+ do Y ..."
smci

229

Đây là cách đơn giản để thêm một cột mới: df['e'] = e


154
Mặc dù số phiếu cao: câu trả lời này là sai . Lưu ý rằng OP có khung dữ liệu với các chỉ mục không liên tục và e( Series(np.random.randn(sLength))) tạo Sê-ri 0-n được lập chỉ mục. Nếu bạn gán cái này cho df1 thì bạn sẽ nhận được một số ô NaN.
joaquin

32
Những gì @joaquin nói là đúng, nhưng miễn là bạn ghi nhớ điều đó, đây là một phím tắt rất hữu ích.
VedTopkar

2
@Eric Leschinski: Không chắc cách bạn chỉnh sửa sẽ giúp ích cho câu hỏi này. my_dataframe = pd.DataFrame(columns=('foo', 'bar')). Hoàn nguyên bản chỉnh sửa của bạn
Kathirmani Sukumar

1
Không có ích gì, vì nếu bạn có nhiều hàng và bạn sử dụng phép gán, nó sẽ gán tất cả các hàng của cột mới với giá trị đó (trong trường hợp của bạn là e) thường không mong muốn.
Paniz

156

Tôi muốn thêm một cột mới, 'e', ​​vào khung dữ liệu hiện có và không thay đổi bất cứ điều gì trong khung dữ liệu. (Sê-ri luôn có cùng độ dài với khung dữ liệu.)

Tôi giả sử rằng các giá trị chỉ số ephù hợp với những người trong df1.

Cách dễ nhất để bắt đầu một cột mới có tên evà gán cho nó các giá trị từ chuỗi của bạn e:

df['e'] = e.values

gán (Pandas 0.16.0+)

Kể từ Pandas 0.16.0, bạn cũng có thể sử dụng assign, nó gán các cột mới cho DataFrame và trả về một đối tượng mới (một bản sao) với tất cả các cột ban đầu bên cạnh các cột mới.

df1 = df1.assign(e=e.values)

Theo ví dụ này (cũng bao gồm mã nguồn của assignhàm), bạn cũng có thể bao gồm nhiều hơn một cột:

df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
>>> df.assign(mean_a=df.a.mean(), mean_b=df.b.mean())
   a  b  mean_a  mean_b
0  1  3     1.5     3.5
1  2  4     1.5     3.5

Trong bối cảnh với ví dụ của bạn:

np.random.seed(0)
df1 = pd.DataFrame(np.random.randn(10, 4), columns=['a', 'b', 'c', 'd'])
mask = df1.applymap(lambda x: x <-0.7)
df1 = df1[-mask.any(axis=1)]
sLength = len(df1['a'])
e = pd.Series(np.random.randn(sLength))

>>> df1
          a         b         c         d
0  1.764052  0.400157  0.978738  2.240893
2 -0.103219  0.410599  0.144044  1.454274
3  0.761038  0.121675  0.443863  0.333674
7  1.532779  1.469359  0.154947  0.378163
9  1.230291  1.202380 -0.387327 -0.302303

>>> e
0   -1.048553
1   -1.420018
2   -1.706270
3    1.950775
4   -0.509652
dtype: float64

df1 = df1.assign(e=e.values)

>>> df1
          a         b         c         d         e
0  1.764052  0.400157  0.978738  2.240893 -1.048553
2 -0.103219  0.410599  0.144044  1.454274 -1.420018
3  0.761038  0.121675  0.443863  0.333674 -1.706270
7  1.532779  1.469359  0.154947  0.378163  1.950775
9  1.230291  1.202380 -0.387327 -0.302303 -0.509652

Mô tả về tính năng mới này khi nó được giới thiệu lần đầu tiên có thể được tìm thấy ở đây .


2
Bất kỳ nhận xét nào về hiệu suất tương đối của hai phương thức, xem xét rằng phương thức đầu tiên ( df['e'] = e.values) không tạo ra một bản sao của khung dữ liệu, trong khi tùy chọn thứ hai (sử dụng df.assign) thì sao? Trong trường hợp có rất nhiều cột mới được thêm tuần tự và các tệp dữ liệu lớn, tôi mong đợi hiệu năng của phương thức đầu tiên tốt hơn nhiều.
jhin

2
@jhin Có, gán trực tiếp rõ ràng là nhiều nếu bạn đang làm việc trên một khung dữ liệu cố định. Lợi ích của việc sử dụng assignlà khi kết hợp các hoạt động của bạn với nhau.
Alexander

Điều này chắc chắn có vẻ như một sự cân bằng tốt đẹp giữa rõ ràng và ẩn. +1: D
Abe Hoffman

2
Để giải trídf.assign(**df.mean().add_prefix('mean_'))
piRSquared

1
@Owlright Từ câu hỏi, có vẻ như OP chỉ đơn giản là nối các dataframes và bỏ qua chỉ mục. Nếu đây là trường hợp, các phương pháp trên sẽ hoạt động. Nếu một người muốn giữ lại chỉ mục, sau đó sử dụng một cái gì đó như df_new = pd.concat([df1, df2], axis=1), lưu ý rằng ignore_index=Falsetheo mặc định.
Alexander

51

Có vẻ như trong các phiên bản Pandas gần đây, cách để sử dụng là sử dụng df.assign :

df1 = df1.assign(e=np.random.randn(sLength))

Nó không sản xuất SettingWithCopyWarning.


1
Sao chép nhận xét của @smci từ phía trên ... Thay vì nói "hiện tại" hoặc năm tham chiếu, vui lòng tham khảo số phiên bản Pandas
Kyle C

50

Làm điều này trực tiếp qua NumPy sẽ hiệu quả nhất:

df1['e'] = np.random.randn(sLength)

Lưu ý đề xuất ban đầu (rất cũ) của tôi là sử dụng map(chậm hơn nhiều):

df1['e'] = df1['a'].map(lambda x: np.random.random())

1
cảm ơn câu trả lời của bạn, như tôi đã đưa ra, tôi có thể sửa đổi mã của bạn, .mapđể sử dụng chuỗi hiện có thay vì lambdakhông? Tôi cố gắng df1['e'] = df1['a'].map(lambda x: e)hoặc df1['e'] = df1['a'].map(e)nó không phải là những gì tôi cần. (Tôi mới biết về pyhon và câu trả lời trước đó của bạn đã giúp tôi)
tomasz74

@ tomasz74 nếu bạn đã có eSê-ri thì bạn không cần sử dụng map, hãy sử dụng df['e']=e(câu trả lời @joaquins).
Andy Hayden

49

Bài tập cột siêu đơn giản

Một khung dữ liệu gấu trúc được triển khai dưới dạng một lệnh của các cột.

Điều này có nghĩa là __getitem__ []không chỉ có thể được sử dụng để có được một cột nhất định mà còn __setitem__ [] =có thể được sử dụng để gán một cột mới.

Ví dụ, dataframe này có thể có một cột thêm vào nó bằng cách đơn giản bằng cách sử dụng []accessor

    size      name color
0    big      rose   red
1  small    violet  blue
2  small     tulip   red
3  small  harebell  blue

df['protected'] = ['no', 'no', 'no', 'yes']

    size      name color protected
0    big      rose   red        no
1  small    violet  blue        no
2  small     tulip   red        no
3  small  harebell  blue       yes

Lưu ý rằng điều này hoạt động ngay cả khi chỉ mục của khung dữ liệu bị tắt.

df.index = [3,2,1,0]
df['protected'] = ['no', 'no', 'no', 'yes']
    size      name color protected
3    big      rose   red        no
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue       yes

[] = là cách để đi, nhưng xem ra!

Tuy nhiên, nếu bạn có một pd.Seriesvà cố gắng gán nó vào một khung dữ liệu nơi các chỉ mục bị tắt, bạn sẽ gặp rắc rối. Xem ví dụ:

df['protected'] = pd.Series(['no', 'no', 'no', 'yes'])
    size      name color protected
3    big      rose   red       yes
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue        no

Điều này là do pd.Seriesmặc định có một chỉ số được liệt kê từ 0 đến n. Và [] =phương pháp gấu trúc cố gắng trở nên "thông minh"

Điều gì thực sự đang diễn ra.

Khi bạn sử dụng [] =phương thức gấu trúc đang lặng lẽ thực hiện phép nối ngoài hoặc hợp nhất bên ngoài bằng cách sử dụng chỉ mục của khung dữ liệu bên trái và chỉ mục của chuỗi bên phải.df['column'] = series

Lưu ý bên

Điều này nhanh chóng gây ra sự bất hòa về nhận thức, vì []=phương pháp này đang cố gắng thực hiện nhiều thứ khác nhau tùy thuộc vào đầu vào và kết quả không thể dự đoán được trừ khi bạn chỉ biết gấu trúc hoạt động như thế nào. Do đó tôi sẽ khuyên chống lại các []=cơ sở mã, nhưng khi khám phá dữ liệu trong một cuốn sổ tay, nó vẫn ổn.

Đi xung quanh vấn đề

Nếu bạn có một pd.Series và muốn nó được gán từ trên xuống dưới hoặc nếu bạn đang mã hóa mã sản xuất và bạn không chắc chắn về thứ tự chỉ mục, thì đáng để bảo vệ cho loại vấn đề này.

Bạn có thể hạ thấp pd.Seriesđến một np.ndarrayhoặc một list, điều này sẽ thực hiện các mẹo.

df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values

hoặc là

df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))

Nhưng điều này không rõ ràng lắm.

Một số lập trình viên có thể đi cùng và nói "Này, điều này có vẻ dư thừa, tôi sẽ chỉ tối ưu hóa điều này".

Cách rõ ràng

Đặt chỉ mục của pd.Seriesthành là chỉ mục của dflà rõ ràng.

df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)

Hoặc thực tế hơn, bạn có thể pd.Seriesđã có sẵn.

protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index

3     no
2     no
1     no
0    yes

Bây giờ có thể được chỉ định

df['protected'] = protected_series

    size      name color protected
3    big      rose   red        no
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue       yes

Cách khác với df.reset_index()

Vì sự bất đồng về chỉ số là vấn đề, nếu bạn cảm thấy rằng chỉ mục của khung dữ liệu không nên ra lệnh, bạn có thể bỏ chỉ mục, điều này sẽ nhanh hơn, nhưng nó không sạch lắm, vì chức năng của bạn bây giờ có thể thực hiện hai điều.

df.reset_index(drop=True)
protected_series.reset_index(drop=True)
df['protected'] = protected_series

    size      name color protected
0    big      rose   red        no
1  small    violet  blue        no
2  small     tulip   red        no
3  small  harebell  blue       yes

Lưu ý về df.assign

Trong khi df.assignlàm cho nó rõ ràng hơn những gì bạn đang làm, nó thực sự có tất cả các vấn đề tương tự như ở trên[]=

df.assign(protected=pd.Series(['no', 'no', 'no', 'yes']))
    size      name color protected
3    big      rose   red       yes
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue        no

Chỉ cần xem ra df.assignrằng cột của bạn không được gọi self. Nó sẽ gây ra lỗi. Điều này làm cho df.assign có mùi , vì có những loại tạo tác trong chức năng.

df.assign(self=pd.Series(['no', 'no', 'no', 'yes'])
TypeError: assign() got multiple values for keyword argument 'self'

Bạn có thể nói, "Chà, tôi sẽ không sử dụng selfsau đó". Nhưng ai biết chức năng này thay đổi như thế nào trong tương lai để hỗ trợ các đối số mới. Có thể tên cột của bạn sẽ là một đối số trong bản cập nhật mới của gấu trúc, gây ra vấn đề với việc nâng cấp.


6
" Khi bạn sử dụng [] =phương pháp gấu trúc đang lặng lẽ thực hiện nối ngoài hoặc hợp nhất bên ngoài ". Đây là phần thông tin quan trọng nhất trong toàn bộ chủ đề. Nhưng bạn có thể cung cấp liên kết đến tài liệu chính thức về cách thức []=vận hành?
Lightman

25

Cách dễ nhất: -

data['new_col'] = list_of_values

data.loc[ : , 'new_col'] = list_of_values

Bằng cách này, bạn tránh được thứ được gọi là lập chỉ mục chuỗi khi đặt giá trị mới trong đối tượng gấu trúc. Nhấn vào đây để đọc thêm .


23

Nếu bạn muốn đặt toàn bộ cột mới thành giá trị cơ sở ban đầu (ví dụ: None ), bạn có thể thực hiện việc này:df1['e'] = None

Điều này thực sự sẽ gán loại "đối tượng" cho ô. Vì vậy, sau này bạn có thể đặt các loại dữ liệu phức tạp, như danh sách, vào các ô riêng lẻ.


1
điều này làm tăng một thiết lập với chế độ chỉnh sửa
00__00__00

1
df ['E'] = '' cũng hoạt động nếu ai đó muốn thêm một cột trống
debaonline4u

21

Tôi đã nhận được sự sợ hãi SettingWithCopyWarningvà nó đã không được sửa bằng cách sử dụng cú pháp iloc. DataFrame của tôi được tạo bởi read_sql từ nguồn ODBC. Sử dụng một đề xuất của lowTech ở trên, những điều sau đây có hiệu quả với tôi:

df.insert(len(df.columns), 'e', pd.Series(np.random.randn(sLength),  index=df.index))

Điều này làm việc tốt để chèn cột ở cuối. Tôi không biết nó có hiệu quả nhất không, nhưng tôi không thích những thông điệp cảnh báo. Tôi nghĩ rằng có một giải pháp tốt hơn, nhưng tôi không thể tìm thấy nó và tôi nghĩ rằng nó phụ thuộc vào một số khía cạnh của chỉ số.
Lưu ý . Rằng điều này chỉ hoạt động một lần và sẽ đưa ra một thông báo lỗi nếu cố gắng ghi đè và cột hiện có.
Lưu ý Như trên và từ 0.16.0 gán là giải pháp tốt nhất. Xem tài liệu http://pandas.pydata.org/pandas-docs/urdy/generated/pandas.DataFrame.assign.html#pandas.DataFrame.assign Hoạt động tốt cho loại luồng dữ liệu mà bạn không ghi đè lên các giá trị trung gian của mình.


Đây là cách duy nhất phù hợp với tôi trong năm 2019!
hydradon

14
  1. Đầu tiên tạo một con trăn list_of_ecó dữ liệu liên quan.
  2. Dùng cái này: df['e'] = list_of_e

1
Tôi thực sự không hiểu, tại sao đây không phải là câu trả lời ưa thích. Trong trường hợp bạn có pd.Series, tolist()lệnh có thể hữu ích.
Vì vậy,

11

Nếu cột bạn đang cố thêm là một biến chuỗi thì chỉ cần:

df["new_columns_name"]=series_variable_name #this will do it for you

Điều này hoạt động tốt ngay cả khi bạn đang thay thế một cột hiện có. Hãy nhập new_columns_name giống như cột bạn muốn thay thế. Nó sẽ ghi đè lên dữ liệu cột hiện tại bằng dữ liệu chuỗi mới.


10

Nếu khung dữ liệu và đối tượng Sê-ri có cùng chỉ mục ,pandas.concatcũng hoạt động ở đây:

import pandas as pd
df
#          a            b           c           d
#0  0.671399     0.101208   -0.181532    0.241273
#1  0.446172    -0.243316    0.051767    1.577318
#2  0.614758     0.075793   -0.451460   -0.012493

e = pd.Series([-0.335485, -1.166658, -0.385571])    
e
#0   -0.335485
#1   -1.166658
#2   -0.385571
#dtype: float64

# here we need to give the series object a name which converts to the new  column name 
# in the result
df = pd.concat([df, e.rename("e")], axis=1)
df

#          a            b           c           d           e
#0  0.671399     0.101208   -0.181532    0.241273   -0.335485
#1  0.446172    -0.243316    0.051767    1.577318   -1.166658
#2  0.614758     0.075793   -0.451460   -0.012493   -0.385571

Trong trường hợp họ không có cùng chỉ số:

e.index = df.index
df = pd.concat([df, e.rename("e")], axis=1)

10

Hoàn hảo:

df.loc[:, 'NewCol'] = 'New_Val'

Thí dụ:

df = pd.DataFrame(data=np.random.randn(20, 4), columns=['A', 'B', 'C', 'D'])

df

           A         B         C         D
0  -0.761269  0.477348  1.170614  0.752714
1   1.217250 -0.930860 -0.769324 -0.408642
2  -0.619679 -1.227659 -0.259135  1.700294
3  -0.147354  0.778707  0.479145  2.284143
4  -0.529529  0.000571  0.913779  1.395894
5   2.592400  0.637253  1.441096 -0.631468
6   0.757178  0.240012 -0.553820  1.177202
7  -0.986128 -1.313843  0.788589 -0.707836
8   0.606985 -2.232903 -1.358107 -2.855494
9  -0.692013  0.671866  1.179466 -1.180351
10 -1.093707 -0.530600  0.182926 -1.296494
11 -0.143273 -0.503199 -1.328728  0.610552
12 -0.923110 -1.365890 -1.366202 -1.185999
13 -2.026832  0.273593 -0.440426 -0.627423
14 -0.054503 -0.788866 -0.228088 -0.404783
15  0.955298 -1.430019  1.434071 -0.088215
16 -0.227946  0.047462  0.373573 -0.111675
17  1.627912  0.043611  1.743403 -0.012714
18  0.693458  0.144327  0.329500 -0.655045
19  0.104425  0.037412  0.450598 -0.923387


df.drop([3, 5, 8, 10, 18], inplace=True)

df

           A         B         C         D
0  -0.761269  0.477348  1.170614  0.752714
1   1.217250 -0.930860 -0.769324 -0.408642
2  -0.619679 -1.227659 -0.259135  1.700294
4  -0.529529  0.000571  0.913779  1.395894
6   0.757178  0.240012 -0.553820  1.177202
7  -0.986128 -1.313843  0.788589 -0.707836
9  -0.692013  0.671866  1.179466 -1.180351
11 -0.143273 -0.503199 -1.328728  0.610552
12 -0.923110 -1.365890 -1.366202 -1.185999
13 -2.026832  0.273593 -0.440426 -0.627423
14 -0.054503 -0.788866 -0.228088 -0.404783
15  0.955298 -1.430019  1.434071 -0.088215
16 -0.227946  0.047462  0.373573 -0.111675
17  1.627912  0.043611  1.743403 -0.012714
19  0.104425  0.037412  0.450598 -0.923387

df.loc[:, 'NewCol'] = 0

df
           A         B         C         D  NewCol
0  -0.761269  0.477348  1.170614  0.752714       0
1   1.217250 -0.930860 -0.769324 -0.408642       0
2  -0.619679 -1.227659 -0.259135  1.700294       0
4  -0.529529  0.000571  0.913779  1.395894       0
6   0.757178  0.240012 -0.553820  1.177202       0
7  -0.986128 -1.313843  0.788589 -0.707836       0
9  -0.692013  0.671866  1.179466 -1.180351       0
11 -0.143273 -0.503199 -1.328728  0.610552       0
12 -0.923110 -1.365890 -1.366202 -1.185999       0
13 -2.026832  0.273593 -0.440426 -0.627423       0
14 -0.054503 -0.788866 -0.228088 -0.404783       0
15  0.955298 -1.430019  1.434071 -0.088215       0
16 -0.227946  0.047462  0.373573 -0.111675       0
17  1.627912  0.043611  1.743403 -0.012714       0
19  0.104425  0.037412  0.450598 -0.923387       0

2
Không ngu ngốc. Điều này không giải quyết câu hỏi của OP, đây là trường hợp các chỉ số của khung dữ liệu hiện có và chuỗi mới không được căn chỉnh.
Alexander

7

Hãy để tôi nói thêm rằng, giống như với hum3 , .locđã không giải quyết được SettingWithCopyWarningvà tôi phải dùng đến df.insert(). Trong trường hợp của tôi, dương tính giả được tạo ra bởi lập chỉ mục chuỗi "giả" dict['a']['e'], 'e'cột mới ở đâu và dict['a']là một DataFrame đến từ từ điển.

Cũng lưu ý rằng nếu bạn biết bạn đang làm gì, bạn có thể chuyển cảnh báo bằng cách sử dụng pd.options.mode.chained_assignment = None và sử dụng một trong những giải pháp khác được đưa ra ở đây.


7

để chèn một cột mới tại một vị trí nhất định (0 <= loc <= lượng cột) trong khung dữ liệu, chỉ cần sử dụng Dataframe.insert:

DataFrame.insert(loc, column, value)

Do đó, nếu bạn muốn thêm cột e vào cuối khung dữ liệu có tên là df , bạn có thể sử dụng:

e = [-0.335485, -1.166658, -0.385571]    
DataFrame.insert(loc=len(df.columns), column='e', value=e)

giá trị có thể là Sê-ri, số nguyên (trong trường hợp tất cả các ô được điền với một giá trị này) hoặc cấu trúc giống như mảng

https://pandas.pydata.org/pandas-docs/urdy/reference/api/pandas.DataFrame.insert.html


6

Trước khi chỉ định một cột mới, nếu bạn có dữ liệu được lập chỉ mục, bạn cần sắp xếp chỉ mục. Ít nhất trong trường hợp của tôi, tôi đã phải:

data.set_index(['index_column'], inplace=True)
"if index is unsorted, assignment of a new column will fail"        
data.sort_index(inplace = True)
data.loc['index_value1', 'column_y'] = np.random.randn(data.loc['index_value1', 'column_x'].shape[0])

6

Tuy nhiên, một điều cần lưu ý là nếu bạn làm

df1['e'] = Series(np.random.randn(sLength), index=df1.index)

đây thực sự sẽ là một tham gia trái trên df1.index. Vì vậy, nếu bạn muốn có hiệu ứng nối ngoài , giải pháp có lẽ không hoàn hảo của tôi là tạo một khung dữ liệu với các giá trị chỉ mục bao trùm vũ trụ dữ liệu của bạn, sau đó sử dụng mã ở trên. Ví dụ,

data = pd.DataFrame(index=all_possible_values)
df1['e'] = Series(np.random.randn(sLength), index=df1.index)

5

Tôi đang tìm kiếm một cách chung để thêm một cột numpy.nans vào khung dữ liệu mà không bị câm SettingWithCopyWarning.

Từ những điều sau đây:

  • câu trả lời ở đây
  • câu hỏi này về việc chuyển một biến làm đối số từ khóa
  • phương pháp này để tạo ra một numpymảng NaN nội tuyến

Tôi nghĩ ra cái này:

col = 'column_name'
df = df.assign(**{col:numpy.full(len(df), numpy.nan)})

4

Để thêm một cột mới, 'e', ​​vào khung dữ liệu hiện có

 df1.loc[:,'e'] = Series(np.random.randn(sLength))

Nó cũng đưa ra thông điệp cảnh báo
B Furtado

bạn nên sử dụng df1.loc [::, 'e'] = Series (np.random.randn (sLpm))
Hermes Morales

4

Để hoàn thiện - một giải pháp khác sử dụng phương thức DataFrame.eval () :

Dữ liệu:

In [44]: e
Out[44]:
0    1.225506
1   -1.033944
2   -0.498953
3   -0.373332
4    0.615030
5   -0.622436
dtype: float64

In [45]: df1
Out[45]:
          a         b         c         d
0 -0.634222 -0.103264  0.745069  0.801288
4  0.782387 -0.090279  0.757662 -0.602408
5 -0.117456  2.124496  1.057301  0.765466
7  0.767532  0.104304 -0.586850  1.051297
8 -0.103272  0.958334  1.163092  1.182315
9 -0.616254  0.296678 -0.112027  0.679112

Giải pháp:

In [46]: df1.eval("e = @e.values", inplace=True)

In [47]: df1
Out[47]:
          a         b         c         d         e
0 -0.634222 -0.103264  0.745069  0.801288  1.225506
4  0.782387 -0.090279  0.757662 -0.602408 -1.033944
5 -0.117456  2.124496  1.057301  0.765466 -0.498953
7  0.767532  0.104304 -0.586850  1.051297 -0.373332
8 -0.103272  0.958334  1.163092  1.182315  0.615030
9 -0.616254  0.296678 -0.112027  0.679112 -0.622436

4

Để tạo một cột trống

df['i'] = None

3

Sau đây là những gì tôi đã làm ... Nhưng tôi khá mới đối với gấu trúc và thực sự là Python nói chung, vì vậy không có lời hứa.

df = pd.DataFrame([[1, 2], [3, 4], [5,6]], columns=list('AB'))

newCol = [3,5,7]
newName = 'C'

values = np.insert(df.values,df.shape[1],newCol,axis=1)
header = df.columns.values.tolist()
header.append(newName)

df = pd.DataFrame(values,columns=header)

3

Nếu bạn nhận được SettingWithCopyWarning, một cách khắc phục dễ dàng là sao chép DataFrame mà bạn đang cố thêm một cột vào.

df = df.copy()
df['col_name'] = values

10
đó không phải là một ý tưởng tốt. Nếu khung dữ liệu đủ lớn, nó sẽ tốn nhiều bộ nhớ ... Bên cạnh đó, nó sẽ trở thành một cơn ác mộng nếu bạn cứ thêm các cột mỗi lần.
Kevad
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.