错误:float对象没有属性notnull

时间:2017-07-03 04:07:59

标签: python pandas

我有一个数据框:

  a     b     c
0 nan   Y     nan
1  23   N      3
2 nan   N      2
3  44   Y     nan

我希望得到这样的结果:

  a     b     c      d
0 nan   Y     nan   nan
1  23   N      3     96
2 nan   N      2    nan
3  44   Y     nan    44

我希望有一个条件当列a为空时,如果列b为N且列c不为null则d为null,则列d等于列a *列c else列d等于列a

我已完成此代码,但我收到错误:

def f4(row):
    if row['a']==np.nan:
       return np.nan
    elif row['b']=="N" & row(row['c'].notnull()):
       return row['a']*row['c']
    else:
       return row['a']

 DF['P1']=DF.apply(f4,axis=1)

任何人都可以帮我指出我的错误在哪里?我已经参考了这个并尝试了这个,但也得到了错误Creating a new column based on if-elif-else condition

5 个答案:

答案 0 :(得分:8)

您不需要apply,请使用np.where

df['d'] = np.where(df.a.isnull(),
         np.nan,
         np.where((df.b == "N")&(~df.c.isnull()),
                  df.a*df.c,
                  df.a))

输出:

      a  b    c     d
0   NaN  Y  NaN   NaN
1  23.0  N  3.0  69.0
2   NaN  N  2.0   NaN
3  44.0  Y  NaN  44.0

答案 1 :(得分:7)

由于您只想传播Nan,因此将列相乘可以为您解决这个问题:

>>> df = pd.read_clipboard()
>>> df
      a  b    c
0   NaN  Y  NaN
1  23.0  N  3.0
2   NaN  N  2.0
3  44.0  Y  NaN
>>> df.a * df.c
0     NaN
1    69.0
2     NaN
3     NaN
dtype: float64
>>>

如果您想在有条件的情况下执行此操作,可以在此处使用np.where而不是.apply。您只需要以下内容:

>>> df
      a  b    c
0   NaN  Y  NaN
1  23.0  N  3.0
2   NaN  N  2.0
3  44.0  Y  NaN
>>> np.where(df.b == 'N', df.a*df.c, df.a)
array([ nan,  69.,  nan,  44.])

这是涉及Nan的大多数操作的默认行为。因此,您可以简单地分配上述结果:

>>> df['d'] = np.where(df.b == 'N', df.a*df.c, df.a)
>>> df
      a  b    c     d
0   NaN  Y  NaN   NaN
1  23.0  N  3.0  69.0
2   NaN  N  2.0   NaN
3  44.0  Y  NaN  44.0
>>>

只是详细说明这一点:

np.where(df.b == 'N', df.a*df.c, df.a)

正在做,您可以将其视为"其中df.b ==' N',给我df.a * df.c的结果,否则,只给我{{1 }}:

df.a

另请注意,如果您的数据框架略有不同:

>>> np.where(df.b == 'N', df.a*df.c, df.a)
array([ nan,  69.,  nan,  44.])

然后以下内容不等同于:

>>> df
      a  b    c
0   NaN  Y  NaN
1  23.0  Y  3.0
2   NaN  N  2.0
3  44.0  Y  NaN
>>> df.loc[0,'a'] = 99
>>> df.loc[0, 'b']= 'N'
>>> df
      a  b    c
0  99.0  N  NaN
1  23.0  N  3.0
2   NaN  N  2.0
3  44.0  Y  NaN

所以你可能想要使用稍微冗长的一些:

>>> np.where(df.b == 'N', df.a*df.c, df.a)
array([ nan,  69.,  nan,  44.])
>>> np.where((df.b == 'N') & (~df.c.isnull()), df.a*df.c, df.a)
array([ 99.,  69.,  nan,  44.])

答案 2 :(得分:5)

你可以尝试

df['d'] = np.where((df.b == 'N') & (pd.notnull(df.c)), df.a*df.c, np.where(pd.notnull(df.a), df.a, np.nan))


    a       b   c      d
0   NaN     Y   NaN    NaN
1   23.0    N   3.0    69.0
2   NaN     N   2.0    NaN
3   44.0    Y   NaN    44.0

请参阅documentation了解pandas notnull,在当前代码中,您只需将series.notnull更改为pd.notnull(系列)即可使用。虽然np.where应该更有效率

def f4(row):
    if row['a']==np.nan:
        return np.nan
    elif (row['b']=="N") & (pd.notnull(row.c)):
        return row['a']*row['c']
    else:
        return row['a']
df['d']=df.apply(f4,axis=1)

答案 3 :(得分:0)

使用

pd.isnull(df['Description'][i])

答案 4 :(得分:0)

使用 pd.isnull() 而不是 == np.nan

示例:

>>> x1 = np.nan
>>> x1 == np.nan
False
>>> pd.isnull(x1)
True
>>> pd.isna(x1)
True

看这个:

The difference between comparison to np.nan and isnull()