2012-11-08 44 views
181

Tôi có một dataframe như sauLàm thế nào tôi có thể thay thế tất cả các giá trị NaN với Zero trong một cột của một dataframe gấu trúc

 itm Date     Amount 
67 420 2012-09-30 00:00:00 65211 
68 421 2012-09-09 00:00:00 29424 
69 421 2012-09-16 00:00:00 29877 
70 421 2012-09-23 00:00:00 30990 
71 421 2012-09-30 00:00:00 61303 
72 485 2012-09-09 00:00:00 71781 
73 485 2012-09-16 00:00:00  NaN 
74 485 2012-09-23 00:00:00 11072 
75 485 2012-09-30 00:00:00 113702 
76 489 2012-09-09 00:00:00 64731 
77 489 2012-09-16 00:00:00  NaN 

khi tôi cố gắng .apply một chức năng để cột Số tiền tôi nhận được lỗi sau .

ValueError: cannot convert float NaN to integer 

Tôi đã thử áp dụng một hàm sử dụng .isnan từ Module Math Tôi đã thử các gấu trúc .replace thuộc tính Tôi đã thử các thuộc tính dữ liệu .sparse từ gấu trúc 0,9 Tôi cũng đã cố gắng nếu NaN == NaN tuyên bố trong một hàm. Tôi cũng đã xem bài viết này How do I replace NA values with zeros in an R dataframe? trong khi xem xét một số bài viết khác. Tất cả các phương pháp tôi đã thử đã không hoạt động hoặc không nhận ra NaN. Bất kỳ gợi ý hoặc giải pháp nào sẽ được đánh giá cao.

+1

Hiển thị cho chúng tôi các mã phần tương ứng, vì bóng tinh thể của tôi bị hỏng. sry ... Và nếu bài viết của Aman không phải là thủ thuật thì bạn cũng có thể truy tìm traceback của mình. ;-) –

Trả lời

328

Tôi tin rằng DataFrame.fillna() sẽ thực hiện việc này cho bạn.

Liên kết tới Tài liệu cho a dataframe và cho a Series.

Ví dụ:

In [7]: df 
Out[7]: 
      0   1 
0  NaN  NaN 
1 -0.494375 0.570994 
2  NaN  NaN 
3 1.876360 -0.229738 
4  NaN  NaN 

In [8]: df.fillna(0) 
Out[8]: 
      0   1 
0 0.000000 0.000000 
1 -0.494375 0.570994 
2 0.000000 0.000000 
3 1.876360 -0.229738 
4 0.000000 0.000000 

Để lấp đầy Nans chỉ trong một cột, chọn chỉ cột đó. trong trường hợp này tôi đang sử dụng inplace = True để thực sự thay đổi nội dung của df.

In [12]: df[1].fillna(0, inplace=True) 
Out[12]: 
0 0.000000 
1 0.570994 
2 0.000000 
3 -0.229738 
4 0.000000 
Name: 1 

In [13]: df 
Out[13]: 
      0   1 
0  NaN 0.000000 
1 -0.494375 0.570994 
2  NaN 0.000000 
3 1.876360 -0.229738 
4  NaN 0.000000 
+0

Có đảm bảo rằng 'df [1]' là một khung nhìn chứ không phải là bản sao của DF gốc? Rõ ràng, nếu có một tình huống hiếm hoi mà đó là một bản sao, nó sẽ gây ra một lỗi siêu phiền hà. Có một tuyên bố rõ ràng về điều đó trong tài liệu về gấu trúc không? – max

+0

@max Xem phần này, có thể giải quyết câu hỏi của bạn: http://stackoverflow.com/questions/23296282/what-rules-does-pandas-use-to-generate-a-view-vs-a-copy – Aman

+0

Cảm ơn. Sự hiểu biết của tôi có đúng trong câu trả lời đó là "chỉ mục được đặt" là hoạt động lập chỉ mục ngoài cùng (được thực hiện ngay trước khi gán hay không. Do đó, bất kỳ phép gán nào chỉ sử dụng một trình chỉ mục duy nhất được đảm bảo an toàn, làm cho mã của bạn an toàn? – max

16

Tôi chỉ muốn cung cấp một chút bản cập nhật/trường hợp đặc biệt vì có vẻ như mọi người vẫn đến đây. Nếu bạn đang sử dụng một multi-index hoặc bằng cách sử dụng một slicer index, tùy chọn inplace = True có thể không đủ để cập nhật slice mà bạn đã chọn. Ví dụ, ở một mức độ 2x2 đa chỉ số này sẽ không thay đổi bất kỳ giá trị (như của gấu trúc 0,15):

idx = pd.IndexSlice 
df.loc[idx[:,mask_1],idx[mask_2,:]].fillna(value=0,inplace=True) 

Các "vấn đề" là chaining phá vỡ khả năng fillna để cập nhật các dataframe gốc. Tôi đặt "vấn đề" trong dấu ngoặc kép vì có những lý do chính đáng cho các quyết định thiết kế dẫn đến việc không diễn giải thông qua các chuỗi này trong các tình huống nhất định. Ngoài ra, đây là một ví dụ phức tạp (mặc dù tôi thực sự chạy vào nó), nhưng điều tương tự cũng có thể áp dụng cho các mức chỉ mục ít hơn tùy thuộc vào cách bạn cắt.

Giải pháp là DataFrame.update:

df.update(df.loc[idx[:,mask_1],idx[[mask_2],:]].fillna(value=0)) 

Đó là một dòng, đọc khá tốt (loại) và loại bỏ bất cứ rối tung không cần thiết với các biến trung gian hoặc vòng trong khi cho phép bạn áp dụng cho bất kỳ fillna đa cấp lát bạn thích!

Nếu bất kỳ ai cũng có thể tìm thấy các địa điểm này không hiệu quả, hãy đăng trong nhận xét, tôi đã làm rối tung nó và xem mã nguồn và dường như giải quyết ít nhất vấn đề về đa chỉ mục của tôi.

12

Mã bên dưới hoạt động cho tôi.

import pandas 

df = pandas.read_csv('somefile.txt') 

df = df.fillna(0) 
33

Không đảm bảo rằng việc cắt sẽ trả về chế độ xem hoặc bản sao.Bạn có thể làm

df['column']=df['column'].fillna(value) 
+4

Chỉ phát hiện ra sự cố "inplace = True". Câu trả lời này tránh được vấn đề và tôi nghĩ là giải pháp sạch nhất được trình bày. – TimCera

9

Bạn có thể sử dụng để thay đổi replaceNaN-0:

import pandas as pd 
import numpy as np 

# for column 
df['column'] = df['column'].replace(np.nan, 0) 

# for whole dataframe 
df = df.replace(np.nan, 0) 

# inplace 
df.replace(np.nan, 0, inplace=True) 
2

fillna() là cách tốt nhất để làm điều đó. Mã -

#fill all Nan value with zero 
df = df.fillna(0) 

Bạn cũng có thể sử dụng inplace nếu bạn không muốn sử dụng 'df = df.fillna (giá trị)'. Mã -

df.fillna(0, inplace=True) 
2

Bạn nên sử dụng fillna(). Nó làm việc cho tôi.

df = df.fillna(value_to_replace_null) 
Các vấn đề liên quan