首页 > 解决方案 > 如何过滤包含列表中任何字符串的 Pandas Dataframe 行?

问题描述

我有具有以下值的数据框:

  A                    B
["I need avocado"   "something"]
["something"      "I eat margarina"]

我想找到以下行:

在行的任何列中,列的值都包含在列表中。例如,对于列表:

["apple","avocado","bannana"]

只有这一行应该匹配:[“我需要鳄梨”“某事”]

这条线不起作用:

dataFiltered[dataFiltered[col].str.contains(*includeKeywords)]

回报:

{TypeError}unsupported operand type(s) for &: 'str' and 'int'

我应该怎么办?

标签: pythonpandasdataframesearchfilter

解决方案


设置

df = pd.DataFrame(dict(
    A=['I need avocado', 'something', 'useless', 'nothing'],
    B=['something', 'I eat margarina', 'eat apple', 'more nothing']
))
includeKeywords = ["apple", "avocado", "bannana"]

问题

                A                B
0  I need avocado        something  # True 'avocado' in A
1       something  I eat margarina
2         useless        eat apple  # True 'apple' in B
3         nothing     more nothing

解决方案


df[df.stack().str.contains('|'.join(includeKeywords)).any(level=0)]

                A          B
0  I need avocado  something
2         useless  eat apple

细节

这会产生一个regex搜索字符串。在regex'|'意味着or。因此,对于regex搜索,这表示 match 'apple''avocado''bannana'

kwstr = '|'.join(includeKeywords)
print(kwstr)

apple|avocado|bannana

堆叠将使我们的DataFrame

df.stack()

0  A     I need avocado
   B          something
1  A          something
   B    I eat margarina
2  A            useless
   B          eat apple
3  A            nothing
   B       more nothing
dtype: object

幸运的是,该pandas.Series.str.contains方法可以处理regex并且会产生一个布尔值Series

df.stack().str.contains(kwstr)

0  A     True
   B    False
1  A    False
   B    False
2  A    False
   B     True
3  A    False
   B    False
dtype: bool

此时我们可以pandas.Series.any通过暗示它只关心它来巧妙地使用level=0

mask = df.stack().str.contains(kwstr).any(level=0)
mask

0     True
1    False
2     True
3    False
dtype: bool

通过使用level=0,我们在结果中保留了原始索引Series。这使其非常适合过滤df

df[mask]

                A          B
0  I need avocado  something
2         useless  eat apple

推荐阅读