Python pandas 在列值不为NULL时应用函数

50 投票
7 回答
171862 浏览
提问于 2025-04-30 05:10

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

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

我想对某一列没有空值的行应用一个简单的函数。我的函数尽可能简单:

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'列是否有空值,pd.notnull()也能很好地工作。但是如果我选择'c'列,它里面包含列表对象:

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

那么我就会收到以下错误信息:ValueError: ('数组中有多个元素的真值是模糊的。请使用a.any()或a.all()',u'发生在索引1')

有没有人知道为什么pd.notnull()只对整数和字符串列有效,而对'列表列'无效?

有没有更好的方法来检查'C'列中的空值,而不是这样:

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

谢谢!

暂无标签

7 个回答

1

添加以下的IF条件,当它为真时返回NONE

def funtion_name(input):
    if (pd.isnull(input)==False)
        return np.NAN
     //Rest funtion code//
3

试试这个...

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

这个例子只是给逗号加了一个转义字符,前提是这个值不是空的。

6

还有一种方法就是直接使用 row.notnull().all()(不需要 numpy),下面是一个例子:

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

这里是一个关于你数据框的完整例子:

>>> 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

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

在这里输入图片描述

21

我有一列数据,里面包含了一些列表和NaN(表示缺失值)。所以,下面这个方法对我有效。

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

问题在于 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

撰写回答