按照特定列的可能前缀列表过滤数据框。

5
我将尝试做的是:
options = ['abc', 'def']
df[any(df['a'].str.startswith(start) for start in options)]

我希望应用过滤器,只保留在“a”列中以给定选项之一开头的条目。

下面的代码可以工作,但我需要它能够使用多个前缀选项……

start = 'abc'
df[df['a'].str.startswith(start)]

错误信息是:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

阅读Series的真值是模糊的。使用a.empty、a.bool()、a.item()、a.any()或a.all(),但还不理解如何操作。


请展示您的数据集! - MikiBelavista
3个回答

6

您可以将选项的元组传递给startswith函数

df = pd.DataFrame({'a': ['abcd', 'def5', 'xabc', '5abc1', '9def', 'defabcb']})
options = ['abc', 'def']
df[df.a.str.startswith(tuple(options))]

你将获得:

    a
0   abcd
1   def5
5   defabcb

抱歉,你的解决方案还有其他问题,所以最终我采用了另一种方式 - 这就是为什么我取消了标记。我会添加我的答案。 - Tatiana Goretskaya
发现我做另一件事的原因,并不是你的解决方案的限制,所以我接受了它。谢谢! - Tatiana Goretskaya

2
你可以尝试这个:
mask = np.array([df['a'].str.startswith(start) for start in options]).any(axis=1)

它针对每个start选项创建一个Series,并沿着相应的行应用any

您之前遇到错误是因为内置函数期望得到bool列表,但正如错误消息所示“多值对象的真值是不明确的”,因此您需要使用支持数组的any


谢谢解释!但是Series的any不是返回匹配项之一而不是布尔结果吗? - Tatiana Goretskaya
你的意思是 Series.any() 吗?如果 Series 中有任何一个元素的计算结果为 True,则它返回True,否则返回 False - taras
是的,我感到困惑,因为函数名称相同,但行为略有不同...不过可以将 any([...]) 视为一个函数,它获取数组中任何 True 值,这是相同的。谢谢! - Tatiana Goretskaya
是的,确切地说。相反,你实际需要的是在多个Series逐行应用 any。幸运的是,更简单和更可信的解决方案存在,即通过将元组传递给 startswith(由Vaishali建议)。 - taras

0

另一种解决方案:

# extract all possible values for 'a' column
all_a_values = df['a'].unique()
# filter 'a' column values by my criteria
accepted_a_values = [x for x in all_a_values if any([str(x).startswith(prefix) for prefix in options])]
# apply filter
df = df[df['a'].isin(accepted_a_values))]

从这里获取:删除行和ValueError数组长度不同

@Vaishali提供的解决方案最简单和合乎逻辑,但我也需要遍历accepted_a_values列表。这在问题中没有提到,所以我将她的答案标记为正确。


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