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

261 投票
4 回答
360666 浏览
提问于 2025-04-29 19:11

有没有什么函数可以同时实现 df.isin()df[col].str.contains() 的功能呢?

举个例子,我有一个序列 s = pd.Series(['cat','hat','dog','fog','pet']),我想找出所有包含 ['og', 'at'] 的地方,我希望得到除了 'pet' 以外的所有项。

我有一个解决方案,但感觉不太优雅:

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

有没有更好的方法呢?

暂无标签

4 个回答

1

我也遇到过同样的问题。为了简单明了,你可以在每个条目之间加上一个|,比如fieldname.str.contains("cat|dog") 这样就可以用了。

15

这里有一个可以用一行代码写成的简单函数,也能正常工作:

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

应用这个简单函数:

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
107

你可以单独使用 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 
446

一种方法是使用正则表达式中的 | 符号,来尝试匹配你在 Series 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 一起使用时,会逐个字符地进行字面匹配。

撰写回答