我的数据框的值如下:
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'
我该怎么办?
答案 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
pandas.DataFrame.stack
将df
设为Series
,使我们能够使用pandas.Series.str
访问器功能pandas.Series.str.contains
与'|'.join(includeKeywords)
pandas.Series.any
和参数level=0
,因为我们在堆叠时为索引添加了一个级别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