我有一个包含71列和30597行的数据框。我想用1替换所有非nan条目,用0替换nan值。
最初我在数据帧的每个值上尝试for循环,这花费了太多时间。
然后我使用了 data_new = data.subtract(data),这意味着将数据帧的所有值减去自身,这样我就可以将所有非空值设为0。 但是由于数据框有多个字符串条目,因此发生错误。
答案 0 :(得分:18)
您可以获取df.notnull()
的返回值,False
,其中DataFrame包含NaN
和True
,并将其转换为整数,为您提供{{1}其中DataFrame为0
,{}为NaN
:
1
如果您真的想要写入原始DataFrame,这将有效:
newdf = df.notnull().astype('int')
答案 1 :(得分:11)
notnull
使用astype
和int
的{{1}}投射布尔值:
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
答案 2 :(得分:3)
DataFrame上有一个方法.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
答案 3 :(得分:3)
我做了很多数据分析,并且有兴趣寻找新的/更快的方法来执行操作。我从未遇到过jezrael的方法,所以我很想将它与我常用的方法进行比较(即用索引代替)。注意:这不是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秒的时间。很明显谁是胜利者。
答案 4 :(得分:2)
我建议制作一个新专栏,而不仅仅是替换。如有必要,您始终可以删除上一列,但通过另一个操作填充列的源始终是有帮助的。
e.g。如果df ['col1']是现有列
df['col2'] = df['col1'].apply(lambda x: 1 if not pd.isnull(x) else np.nan)
其中col2是新列。如果col2有字符串条目,也应该有效。
答案 5 :(得分:0)
使用:df.fillna(0)
用0填充NaN。
答案 6 :(得分:0)
在这里,我会建议您选择一个特定的列,如果该列中的行是NaN,则将其替换为0或该列中的值替换为1
下面这行会将您的列更改为0
df.YourColumnName.fillna(0,inplace=True)
现在,非Nan部分的其余部分将被以下代码替换为
df["YourColumnName"]=df["YourColumnName"].apply(lambda x: 1 if x!=0 else 0)
可以通过不定义列名来将相同的值应用于整个数据框
答案 7 :(得分:0)
获取fmarc的答案:
df.loc[~df.isnull()] = 1 # not nan
df.loc[df.isnull()] = 0 # nan
上面的代码对我不起作用,下面的代码对我有用。
df[~df.isnull()] = 1 # not nan
df[df.isnull()] = 0 # nan
使用大熊猫0.25.3
如果只想更改特定列中的值,则可能需要创建一个临时数据框并将其分配给原始数据框的列:
change_col = ['a', 'b']
tmp = df[change_col]
tmp[tmp.isnull()]='xxx'
df[change_col]=tmp
答案 8 :(得分:0)
通常有两个步骤 - 替换所有非 NAN 值,然后替换所有 NAN 值。
dataframe.where(~dataframe.notna(), 1)
- 此行将所有非 nan 值替换为 1。dataframe.fillna(0)
- 此行将所有 NAN 替换为 0旁注:如果您查看 pandas 文档,.where
会替换所有值,即 False
- 这很重要。这就是为什么我们使用反转来创建掩码 ~dataframe.notna()
,.where()
将通过它替换值
答案 9 :(得分:0)
试试这个:
df.notnull().mul(1)