如何在pandas中检查一个元素是否为空列表?

29

我有一个数据框(df)中的一列存储了一个列表(list),而且其中有些行在列表中有空项。例如:

[]

["X", "Y"]

[]

等等...

如何只选择那些列表不为空的行?

以下代码无法实现。

df[df["col"] != []] # ValueError: Lengths must match to compare
df[pd.notnull(df["col"])] # The code doesn't issue an error but the result includes an empty list
df[len(df["col"]) != 0] # KeyError: True

它们是否总是列表,还是需要检查它是否为列表? - piRSquared
5个回答

39
你可以这样做:
df[df["col"].str.len() != 0]

例子:

import pandas as pd

df = pd.DataFrame({"col": [[1], [2, 3], [], [4, 5, 6], []]}, dtype=object)
print(df[df["col"].str.len() != 0])
#          col
# 0        [1]
# 1     [2, 3]
# 3  [4, 5, 6]

代码可以运行,谢谢。但是你能否给我更多的解释,特别是为什么在这里需要使用.str?这非常不直观,除非你从头到尾阅读官方文档,否则几乎不可能理解代码。 - Blaszard
5
这有点“技巧性”。.str下的函数是用于处理字符串数据的,它们并不是真正向量化的,只是将函数应用于每个数据项。在len的情况下,它只是将函数len应用于每个对象,因此对于字符串、列表或任何可以应用len函数的对象都可以正常工作。Quan Hoang的回答可能更有意义。 - jdehesa
1
同意jdehesa的观点,这个str len方法是一个好的易记技巧。但要注意在大型数据框上的执行时间。Quang Hoang方法似乎是矢量化的,并且速度要快得多。 - weezilla

29

这可能是最有效的解决方案。

df[df["col"].astype(bool)]

在Python中,检查列表l是否为空的最有效方法是只需编写if l: ...。换句话说,bool(l)可以返回一个布尔值,确定列表l是否为空。因此,df["col"].astype("bool")也会按预期工作,这并不奇怪。 - GZ0
在计算方面高效,还是代码紧凑方面高效? - jtlz2

16

试试这个:

df[df['col'].apply(len).gt(0)]

1
虽然你的回答非常简洁,但我喜欢它,因为它清楚地表明需要一个列表(或字符串?)且长度必须大于0,即非空列表或非空字符串。其他布尔型回答的问题在于需要知道空列表会被评估为False(没问题),并且需要弄清楚这里应用的是什么测试(因为布尔型可能会对其他类型进行不透明的测试)。所以,很好的回答! - jtlz2

4

bool

在布尔上下文中,一个空列表是False。我们称一个空列表为假值。了解哪些对象是假值和真值对程序员很有帮助。

您还可以使用布尔列表(而不仅仅是布尔序列)来切片数据框。因此,我将使用推导式来加快检查速度。

df[[bool(x) for x in df.col]]

或者使用更少的字符

df[[*map(bool, df.col)]]

一个程序员了解什么是假值和真值对他的工作非常有帮助。参考资料呢? :) - jtlz2

0

你可以使用 str.len() 来检查列表是否为空,然后取反:

df[df["col"].str.len() != 0]
...

str.len 是 Python 内置函数,用于返回对象的长度。

您的输出应该是预期的输出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接