Pandas dataframe fillna () chỉ một số cột tại chỗ


144

Tôi đang cố gắng điền vào bất kỳ giá trị nào trong khung dữ liệu Pandas bằng 0 chỉ cho một số tập hợp con của các cột.

Khi tôi làm:

import pandas as pd
df = pd.DataFrame(data={'a':[1,2,3,None],'b':[4,5,None,6],'c':[None,None,7,8]})
print df
df.fillna(value=0, inplace=True)
print df

Đầu ra:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  NaN  7.0
3  NaN  6.0  8.0
     a    b    c
0  1.0  4.0  0.0
1  2.0  5.0  0.0
2  3.0  0.0  7.0
3  0.0  6.0  8.0

Nó thay thế mọi thứ Nonebằng 0. Những gì tôi muốn làm là, chỉ thay thế Nones trong cột ab, nhưng không c.

Cách nào là tốt nhất để thực hiện việc này?

Câu trả lời:


218

Bạn có thể chọn các cột mong muốn và thực hiện bằng cách gán:

df[['a', 'b']] = df[['a','b']].fillna(value=0)

Kết quả đầu ra như mong đợi:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

Vâng, đây chính xác là những gì tôi muốn! Cảm ơn bạn. Bất kỳ cách nào để làm điều này tại chỗ? Khung dữ liệu ban đầu của tôi là khá lớn.
Sait

1
Tôi không nghĩ có bất kỳ hiệu suất nào đạt được bằng cách thực hiện điều này khi bạn ghi đè lên orig df
EdChum

4
Các locus là không cần thiết ở đây, df[['a', 'b']] = df[['a','b']].fillna(value=0)vẫn sẽ hoạt động
EdChum

2
@EdChum Không tạo ra khung dữ liệu tạm thời và do đó cần thêm bộ nhớ để làm như vậy? (Tôi quan tâm đến bộ nhớ nhiều hơn là sự phức tạp về thời gian.)
Sait

7
Đối với nhiều hoạt động, inplacevẫn sẽ làm việc trên một bản sao. Tôi không biết đó có phải là trường hợp fillnahay không. Xem câu trả lời này từ một trong những nhà phát triển cốt lõi của gấu trúc.
root

85

Bạn có thể sử dụng dict, fillnavới giá trị khác nhau cho cột khác nhau

df.fillna({'a':0,'b':0})
Out[829]: 
     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

Sau khi gán nó trở lại

df=df.fillna({'a':0,'b':0})
df
Out[831]: 
     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

1
thực sự tuyệt vời, Btw cho dict bạn có thể sử dụng fromkeysnếu bạn muốn, +1
U10-Forward

1
Câu trả lời / ví dụ sẽ rõ ràng hơn nếu nó thực sự hiển thị các giá trị khác nhau cho các cột khác nhau.
RufusVS

@RufusVS đúng, nhưng vẫn cố gắng khớp với sản lượng dự kiến ​​của op
YOBEN_S

1
Đây là giải pháp tốt hơn mà câu trả lời được chấp nhận, vì nó tránh được các vấn đề về lập chỉ mục, ví dụ nếu được sử dụng vớidf.fillna({'a':0,'b':0}, inplace=True)
Alex

19

Bạn có thể tránh tạo một bản sao của đối tượng bằng giải pháp của Wen và inplace = True:

df.fillna({'a':0, 'b':0}, inplace=True)
print(df)

Sản lượng nào:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

1
Trong khi điều này là chính xác, tránh một bản sao không nhất thiết phải tốt hơn .
jpp

7

Đây là cách bạn có thể làm tất cả trong một dòng:

df[['a', 'b']].fillna(value=0, inplace=True)

Phân tích: df[['a', 'b']]chọn các cột bạn muốn điền giá trị NaN cho value=0nó , bảo nó điền vào NaN bằng 0 và inplace=Truesẽ thay đổi vĩnh viễn mà không phải tạo bản sao của đối tượng.


7

sử dụng câu trả lời trên cùng tạo ra một cảnh báo về việc thực hiện các thay đổi đối với bản sao của lát cắt df. Giả sử rằng bạn có các cột khác, cách tốt hơn để làm điều này là chuyển từ điển:
df.fillna({'A': 'NA', 'B': 'NA'}, inplace=True)


3

Hoặc một cái gì đó như:

df.loc[df['a'].isnull(),'a']=0
df.loc[df['b'].isnull(),'b']=0

và nếu có thêm:

for i in your_list:
    df.loc[df[i].isnull(),i]=0

0

Đôi khi cú pháp này không hoạt động:

df[['col1','col2']] = df[['col1','col2']].fillna()

Sử dụng như sau thay thế:

df['col1','col2']
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.