如果列值不为NULL,Python pandas将应用函数

时间:2014-10-28 17:15:32

标签: python list pandas null apply

我有一个数据框(在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)

谢谢!

4 个答案:

答案 0 :(得分:17)

问题是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

答案 1 :(得分:3)

另一种方法是只使用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

更友好的截图:-)

enter image description here

答案 2 :(得分:2)

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

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

答案 3 :(得分:0)

尝试...

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

此示例仅在值不为None时将转义符添加到逗号