如何过滤在列表中包含字符串的Pandas Dataframe值?

时间:2019-05-01 18:45:18

标签: python pandas dataframe search filter

我的数据框的值如下:

  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'

我该怎么办?

2 个答案:

答案 0 :(得分:2)

利用any()函数并在df.apply()中使用列表推导功能

df = pd.DataFrame(["I need avocado","I eat margarina"])
print(df)
#                  0
# 0   I need avocado
# 1  I eat margarina

includeKeywords = ["apple","avocado","bannana"]

print(df[df.apply(lambda r: any([kw in r[0] for kw in includeKeywords]), axis=1)])
#                 0
# 0  I need avocado

为使这一点更加清晰,您基本上需要制作一个掩码,每行返回True / False。

mask = [any([kw in r for kw in includeKeywords]) for r in df[0]]
print(mask)

然后您可以使用该遮罩在DataFrame中打印选定的行

# [True, False]
print(df[mask])
#                 0
# 0  I need avocado

我向您展示了这两种方法,因为尽管df.apply()方法仅适用于一个班轮,但与标准列表理解相比,它确实很慢。因此,如果您有足够小的设置,请随时使用df.apply()。否则,我建议对pandas方法使用python理解。

答案 1 :(得分:2)

设置

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搜索,这表示匹配'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