2016-05-31 41 views
8

我有一個包含71列和30597行的數據框。我想用1替換所有non-nan條目,將nan值替換爲0.如何用1替換數據幀的所有非NaN條目並且用0替換所有的NaN

最初我試圖循環使用數據幀的每個值,這花費了太多時間。

然後我用data_new = data.subtract(數據)其意味着減去數據幀到自身的所有的值,這樣我可以使所有的非空值0 但是發生錯誤的數據幀有多個字符串條目。

+0

可能的重複[我如何用一個熊貓數據框的列中的零替換所有的NaN值](http://stackoverflow.com/questions/13295735/how-can-i-replace-all-the- nan-values-with-zero-a-column-of-pandas-datafra) –

回答

4

使用notnullastype鑄造布爾值int

print ((df.notnull()).astype('int')) 

樣品:

import pandas as pd 
import numpy as np 

df = pd.DataFrame({'a': [np.nan, 4, np.nan], 'b': [1,np.nan,3]}) 
print (df) 
    a b 
0 NaN 1.0 
1 4.0 NaN 
2 NaN 3.0 

print (df.notnull()) 
     a  b 
0 False True 
1 True False 
2 False True 

print ((df.notnull()).astype('int')) 
    a b 
0 0 1 
1 1 0 
2 0 1 
9

你可以採取的df.notnull()的返回值,這是False在數據幀中包含NaNTrue否則並將其轉換爲整數,給出0,其中DataFrame爲NaN1否則:

newdf = df.notnull().astype('int') 

如果你真的想寫入原來的數據幀,這將工作:

df.loc[~df.isnull()] = 1 # not nan 
df.loc[df.isnull()] = 0 # nan 
+0

對不起,請不要複製我的答案。我認爲你的版本與我的版本相同,所以我認爲這是沒有必要的。 – jezrael

+1

您是否注意到我在此之前發佈了這個答案? – fmarc

+0

是的,但不是'notnull()'。你的答案是用〜〜isnull()'。它是平等的,所以我認爲你的解決方案和我一樣好。 – jezrael

0

有上DataFrames方法.fillna()它做你需要什麼。例如:

df = df.fillna(0) # Replace all NaN values with zero, returning the modified DataFrame 

df.fillna(0, inplace=True) # Replace all NaN values with zero, updating the DataFrame directly 
0

我會建議做一個新的列,而不僅僅是更換。如有必要,您可以隨時刪除前一列,但對於通過另一列上的操作填充列的源通常有幫助。

例如如果df ['col1']是現有列

df['col2'] = df['col1'].apply(lambda x: 1 if not pd.isnull(x) else np.nan) 

其中col2是新列。如果col2有字符串條目,也應該工作。

0

用途:df.fillna(0)

以0

2

我做了很多的數據分析,並有興趣在尋找開展業務的新/更快的方法來填補NaN的。我從來沒有碰到過以色列的方法,所以我很好奇將其與我通常的方法(即通過索引替換)進行比較。注意:這不是OP問題的答案,而是jezrael方法效率的一個例證。由於這不是一個答案,我會刪除這篇文章,如果人們沒有發現它有用(並被降低爲遺忘!)。如果您認爲我應該刪除它,請留下評論。

我創建了一箇中等大小的數據框,並使用df.notnull()。astype(int)方法和簡單索引(我通常會這樣做)做了多個替換。事實證明,後者慢了大約五倍。只是一個人做大規模的替代品。

from __future__ import division, print_function 

import numpy as np 
import pandas as pd 
import datetime as dt 


# create dataframe with randomly place NaN's 
data = np.ones((1e2,1e2)) 
data.ravel()[np.random.choice(data.size,data.size/10,replace=False)] = np.nan 

df = pd.DataFrame(data=data) 

trials = np.arange(100) 


d1 = dt.datetime.now() 

for r in trials: 
    new_df = df.notnull().astype(int) 

print((dt.datetime.now()-d1).total_seconds()/trials.size) 


# create a dummy copy of df. I use a dummy copy here to prevent biasing the 
# time trial with dataframe copies/creations within the upcoming loop 
df_dummy = df.copy() 

d1 = dt.datetime.now() 

for r in trials: 
    df_dummy[df.isnull()] = 0 
    df_dummy[df.isnull()==False] = 1 

print((dt.datetime.now()-d1).total_seconds()/trials.size) 

這產生的時間分別爲0.142秒和0.685秒。很明顯誰是贏家。