如果列值不为 NULL,则 Python pandas 应用函数
Posted
技术标签:
【中文标题】如果列值不为 NULL,则 Python pandas 应用函数【英文标题】:Python pandas apply function if a column value is not NULL 【发布时间】: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)
谢谢!
【问题讨论】:
【参考方案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】:我有一列包含列表和NaN
s。所以,下一个对我有用。
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 我不知道。如果您愿意,可以提出一个新问题。以上是关于如果列值不为 NULL,则 Python pandas 应用函数的主要内容,如果未能解决你的问题,请参考以下文章