2012-11-08 59 views
181

我有一個數據幀如下我怎麼能代替的大熊貓數據幀的列中的所有NaN值與零的

 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 

當我嘗試。適用的功能,金額列我得到以下錯誤。

ValueError: cannot convert float NaN to integer 

我試圖應用使用.isnan從數學模塊 函數我試圖大熊貓.replace屬性 我試圖從大熊貓.sparse數據屬性0.9 我還試圖如果爲NaN == NaN的一個函數中的語句。 我也看過這篇文章How do I replace NA values with zeros in an R dataframe?,同時看着一些其他的文章。 我試過的所有方法都沒有工作或不認識NaN。 任何提示或解決方案,將不勝感激。

+1

向我們展示相應的代碼部分,因爲我的晶球破碎了atm。 sry ...如果Aman的帖子不包含你的追蹤也包括你的追蹤。 ;-) –

回答

328

我相信DataFrame.fillna()會爲你做這個。

鏈接到文檔a dataframea Series

實施例:

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 

爲了填充的NaN中只有一列,僅選擇該列中。在這種情況下,我使用inplace = True來實際更改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

確保'df [1]'是一個視圖而不是原始DF的副本?顯然,如果出現這種複製情況的情況很少,就會造成一個非常麻煩的錯誤。在熊貓文檔中是否有明確的說明? – max

+0

@max看到這個,可能會解決您的問題:http://stackoverflow.com/questions/23296282/what-rules-does-pandas-use-to-generate-a-view-vs-a-copy – Aman

+0

謝謝。我的理解是正確的,在這個答案中,「設置的索引器」是最外面的索引操作(在賦值之前執行)。因此,只使用單個索引器的任何賦值都是安全的,這使您的代碼安全嗎? – max

16

我只是想提供一些更新/特殊情況,因爲它看起來像人們仍然來到這裏。如果您使用多索引或使用索引切片器,則inplace = True選項可能不足以更新您選擇的切片。例如,在一個2x2的多電平指數這不會改變任何值(如熊貓0.15):

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

「問題」是,鏈打破更新原始數據幀的fillna能力。我把「問題」放在引號中,因爲在某些情況下導致不通過這些鏈條進行解釋的設計決策是有充分理由的。此外,這是一個複雜的例子(雖然我真的遇到它),但同樣可能適用於較少級別的索引,具體取決於你如何分片。

解決的辦法是DataFrame.update:

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

這是一條線,讀得相當好(在某種程度上),並消除了中間變量或循環任何不必要搞亂,同時還可以申請fillna任何多級切片你喜歡!

如果有人可以找到這個地方不起作用請發表評論,我一直在搞這個,看看源代碼,它似乎至少解決了我的多索引切片問題。

12

以下代碼適用於我。

import pandas 

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

df = df.fillna(0) 
33

不保證切片返回視圖或副本。你可以做

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

剛剛發現「inplace = True」問題。這個答案避免了這個問題,我認爲這是最清晰的解決方案。 – TimCera

9

你可以使用replace改變NaN0

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()是做到這一點的最好辦法。代碼 -

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

您還可以使用就地,如果你不希望使用'DF = df.fillna(值)'。代碼 -

df.fillna(0, inplace=True) 
2

您應該使用fillna()。這個對我有用。

df = df.fillna(value_to_replace_null)