我有一个拥有71个列和30597行的数据框。我想将所有非nan值替换为1,将nan值替换为0。
最初,我尝试使用for循环遍历数据框中的每个值,但这花费了太多时间。
然后我使用了data_new=data.subtract(data),意在将数据框的所有值减去自身以使所有非空值变为0。 但由于数据框中存在多个字符串条目,所以出现了一个错误。
df.notnull()
的返回值,其中DataFrame包含NaN
时为False
,否则为True
,然后将其转换为整数,这将使得DataFrame中为NaN
的位置变为0
,其他位置为1
:newdf = df.notnull().astype('int')
如果你真的想要写入原始DataFrame,可以这样做:
df.loc[~df.isnull()] = 1 # not nan
df.loc[df.isnull()] = 0 # nan
notnull()
。你的答案是用 ~isnull()
。而且它是相等的,所以我认为你的解决方案和我的一样好。 - jezrael使用notnull
函数,通过astype
将布尔值转换为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
(df.isnull()).astype('int')
- Chididf['col2'] = df['col1'].apply(lambda x: 1 if not pd.isnull(x) else np.nan)
其中col2是新列。如果col2有字符串条目,也应该有效。
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秒的时间。 显然获胜者是谁。
在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
df.loc[~df.isnull()] = 1 # not nan
df.loc[df.isnull()] = 0 # nan
上面的代码对我不起作用,下面的代码可以。
df[~df.isnull()] = 1 # not nan
df[df.isnull()] = 0 # nan
使用 pandas 0.25.3 版本
如果您只想更改特定列中的值,可能需要创建一个临时数据帧,并将其分配给原始数据帧的列:
change_col = ['a', 'b']
tmp = df[change_col]
tmp[tmp.isnull()]='xxx'
df[change_col]=tmp
df.notnull().mul(1)
df.YourColumnName.fillna(0,inplace=True)
df["YourColumnName"]=df["YourColumnName"].apply(lambda x: 1 if x!=0 else 0)
df.fillna(0)
来将NaN填充为0。一般来说有两个步骤-先替换所有非NAN值,然后替换所有NAN值。
dataframe.where(~dataframe.notna(), 1)
- 这行代码将把所有非nan值替换为1。dataframe.fillna(0)
- 这行代码将把所有NAN替换为0附注:如果您查看pandas文档,.where
会替换所有值,即False
-这很重要。因此,我们使用反转来创建一个掩码~dataframe.notna()
,用于.where()
替换值