如何用1替换数据帧的所有非NaN条目,用0替换所有NaN

时间:2016-05-31 10:50:47

标签: python pandas dataframe

我有一个包含71列和30597行的数据框。我想用1替换所有非nan条目,用0替换nan值。

最初我在数据帧的每个值上尝试for循环,这花费了太多时间。

然后我使用了 data_new = data.subtract(data),这意味着将数据帧的所有值减去自身,这样我就可以将所有非空值设为0。 但是由于数据框有多个字符串条目,因此发生错误。

10 个答案:

答案 0 :(得分:18)

您可以获取df.notnull()的返回值,False,其中DataFrame包含NaNTrue,并将其转换为整数,为您提供{{1}其中DataFrame为0,{}为NaN

1

如果您真的想要写入原始DataFrame,这将有效:

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

答案 1 :(得分:11)

notnull使用astypeint的{​​{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 值。

  1. dataframe.where(~dataframe.notna(), 1) - 此行将所有非 nan 值替换为 1。
  2. dataframe.fillna(0) - 此行将所有 NAN 替换为 0

旁注:如果您查看 pandas 文档,.where 会替换所有值,即 False - 这很重要。这就是为什么我们使用反转来创建掩码 ~dataframe.notna().where() 将通过它替换值

答案 9 :(得分:0)

试试这个:

df.notnull().mul(1)
相关问题