【问题标题】:Python pandas apply function if a column value is not NULL如果列值不为 NULL,则 Python pandas 应用函数
【发布时间】:2014-12-24 05:16:19
【问题描述】:

我有一个数据框(在 Python 2.7 中,pandas 0.15.0):

df=
       A    B               C
0    NaN   11             NaN
1    two  NaN  ['foo', 'bar']
2  three   33             NaN

我想对特定列中不包含 NULL 值的行应用一个简单的函数。我的功能尽可能简单:

def my_func(row):
    print row

我的申请代码如下:

df[['A','B']].apply(lambda x: my_func(x) if(pd.notnull(x[0])) else x, axis = 1)

完美运行。如果我想检查 'B' 列的 NULL 值,pd.notnull() 也可以完美运行。但是,如果我选择包含列表对象的列“C”:

df[['A','C']].apply(lambda x: my_func(x) if(pd.notnull(x[1])) else x, axis = 1)

然后我收到以下错误消息:ValueError: ('The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()', u'occurred at index 1')

有人知道为什么pd.notnull() 只适用于整数和字符串列而不适用于“列表列”吗?

还有更好的方法来检查“C”列中的 NULL 值而不是这个:

df[['A','C']].apply(lambda x: my_func(x) if(str(x[1]) != 'nan') else x, axis = 1)

谢谢!

【问题讨论】:

    标签: python list pandas null apply


    【解决方案1】:

    如果你有一个字符串并且想要应用这个例子的函数: 'September 25, 2021'

    df['Year'] = df['date_added'].apply(lambda x : re.split(' |,', x)[-1] if isinstance(x, str) else np.nan)
    df['Month'] = df['date_added'].apply(lambda x : re.split(' |,', x)[0] if isinstance(x, str) else np.nan )
    

    你可以应用这种方式并使用isinstance(x, str)来避免NaN或任何其他类型,你也可以像这样使用type()

    df['Year'] = df['date_added'].apply(lambda x : re.split(' |,', x)[-1] if type(x)==str else np.nan )
    

    【讨论】:

      【解决方案2】:

      试试……

      df['a'] = df['a'].apply(lambda x: x.replace(',','\,') if x != None else x)
      

      如果值不是 None,此示例只是在逗号中添加转义字符

      【讨论】:

        【解决方案3】:

        我有一列包含列表和NaNs。所以,下一个对我有用。

        df.C.map(lambda x: my_func(x) if type(x) == list else x)
        

        【讨论】:

          【解决方案4】:

          另外一种方法是只使用row.notnull().all()(没有numpy),这里是一个例子:

          df.apply(lambda row: func1(row) if row.notnull().all() else func2(row), axis=1)
          

          这是您的 df 的完整示例:

          >>> d = {'A': [None, 2, 3, 4], 'B': [11, None, 33, 4], 'C': [None, ['a','b'], None, 4]}
          >>> df = pd.DataFrame(d)
          >>> df
               A     B       C
          0  NaN  11.0    None
          1  2.0   NaN  [a, b]
          2  3.0  33.0    None
          3  4.0   4.0       4
          >>> def func1(r):
          ...     return 'No'
          ...
          >>> def func2(r):
          ...     return 'Yes'
          ...
          >>> df.apply(lambda row: func1(row) if row.notnull().all() else func2(row), axis=1)
          0    Yes
          1    Yes
          2    Yes
          3     No
          

          还有一个更友好的截图:-)

          【讨论】:

            【解决方案5】:

            问题是pd.notnull(['foo', 'bar']) 按元素操作并返回array([ True, True], dtype=bool)。您的 if 条件尝试将其转换为布尔值,这就是您遇到异常的时候。

            要修复它,您可以简单地用np.all 包装 isnull 语句:

            df[['A','C']].apply(lambda x: my_func(x) if(np.all(pd.notnull(x[1]))) else x, axis = 1)
            

            现在您会看到np.all(pd.notnull(['foo', 'bar'])) 确实是True

            【讨论】:

            • 请注意,np.all([True, True]) 将返回 True。我认为这对 OP 有用。
            • @PaulH 谢谢。我尝试使用all,但忽略了np.all。问题不在于[True, True],而在于False。虽然all(pd.notnull(None)) 会引发错误,但np.all(pd.notnull(None)) 不会。
            • 谢谢Korem,它有效!我想知道的是,单个 pd.notnull(df['C']) 会返回 False, True, False 而不是 False, [True, True], False
            • @ragesz 我不知道。如果您愿意,可以提出一个新问题。
            猜你喜欢
            • 1970-01-01
            • 2021-04-12
            • 2017-12-24
            • 2016-07-21
            • 2017-09-20
            • 1970-01-01
            • 1970-01-01
            • 2016-06-02
            相关资源
            最近更新 更多