如果列值不为 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】:

我有一列包含列表和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 我不知道。如果您愿意,可以提出一个新问题。

以上是关于如果列值不为 NULL,则 Python pandas 应用函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在mysql中获取值不为null的列名

判断:ORACLE中,用==NULL来判断列值是不是为空,

选择性过滤列值不为空的行 PostgreSQL

mysql if判断字符串比较

查找值不为null的列sql语句

sql怎么判断一个值是不是为空