如何在 pandas 中测试字符串是否包含列表中的子字符串之一?

问题描述 投票:0回答:5

是否有任何函数相当于

df.isin()
df[col].str.contains()
的组合?

例如,假设我有这个系列

s = pd.Series(['cat','hat','dog','fog','pet'])
,我想找到
s
包含任何
['og', 'at']
的所有地方,我想得到除“宠物”之外的所有内容。

我有一个解决方案,但它相当不优雅:

searchfor = ['og', 'at']
found = [s.str.contains(x) for x in searchfor]
result = pd.DataFrame[found]
result.any()

有更好的方法吗?

python string pandas dataframe match
5个回答
430
投票

一种选择是仅使用正则表达式

|
字符来尝试匹配系列中单词中的每个子字符串
s
(仍使用
str.contains
)。

您可以通过将

searchfor
中的单词与
|
:

连接来构建正则表达式
>>> searchfor = ['og', 'at']
>>> s[s.str.contains('|'.join(searchfor))]
0    cat
1    hat
2    dog
3    fog
dtype: object

正如 @AndyHayden 在下面的评论中指出的那样,请注意您的子字符串是否包含特殊字符,例如您想要字面匹配的

$
^
。这些字符在正则表达式的上下文中具有特定的含义,并且会影响匹配。

您可以通过使用

re.escape
:

转义非字母数字字符来使子字符串列表更安全
>>> import re
>>> matches = ['$money', 'x^y']
>>> safe_matches = [re.escape(m) for m in matches]
>>> safe_matches
['\\$money', 'x\\^y']

str.contains
一起使用时,此新列表中的字符串将逐字匹配每个字符。


105
投票

您可以将

str.contains
与正则表达式模式单独使用
OR (|)
:

s[s.str.contains('og|at')]

或者您可以将系列添加到

dataframe
然后使用
str.contains
:

df = pd.DataFrame(s)
df[s.str.contains('og|at')] 

输出:

0 cat
1 hat
2 dog
3 fog 

13
投票

这是一个也可以工作的单行 lambda:

df["TrueFalse"] = df['col1'].apply(lambda x: 1 if any(i in x for i in searchfor) else 0)

输入:

searchfor = ['og', 'at']

df = pd.DataFrame([('cat', 1000.0), ('hat', 2000000.0), ('dog', 1000.0), ('fog', 330000.0),('pet', 330000.0)], columns=['col1', 'col2'])

   col1  col2
0   cat 1000.0
1   hat 2000000.0
2   dog 1000.0
3   fog 330000.0
4   pet 330000.0

应用 Lambda:

df["TrueFalse"] = df['col1'].apply(lambda x: 1 if any(i in x for i in searchfor) else 0)

输出:

    col1    col2        TrueFalse
0   cat     1000.0      1
1   hat     2000000.0   1
2   dog     1000.0      1
3   fog     330000.0    1
4   pet     330000.0    0

0
投票

有同样的问题。在不使其变得太复杂的情况下,您可以在每个条目之间添加

|
,就像
fieldname.str.contains("cat|dog")
一样有效


0
投票

您好,请允许问一些问题。

df.str.contains(“猫|狗”)

我们可以向该方法传递多少个表达式或参数,即(“cat|dog|mice”),这可能吗?

© www.soinside.com 2019 - 2024. All rights reserved.