提问人:ari 提问时间:10/27/2014 最后编辑:smciari 更新时间:10/28/2023 访问量:343384
如何在 pandas 中测试字符串是否包含列表中的子字符串之一?
How to test if a string contains one of the substrings in a list, in pandas?
问:
是否有任何函数等效于 和 的组合?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()
有没有更好的方法可以做到这一点?
答:
436赞
Alex Riley
10/27/2014
#1
一种选择是仅使用正则表达式字符来尝试匹配 Series 中单词中的每个子字符串(仍在使用 )。|
s
str.contains
您可以通过将单词加入 with 来构造正则表达式: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
评论
4赞
goofd
10/27/2014
也许最好添加此链接 pandas.pydata.org/pandas-docs/stable/...。从 pandas 0.15 开始,字符串操作更加简单
7赞
Andy Hayden
10/27/2014
您必须注意的一件事是 searchfor 中的字符串是否具有特殊的正则表达式字符(您可以使用 re.escape 进行映射)。
0赞
Doo Hyun Shin
2/17/2019
我不知道为什么你的方法不适用于“str.startswith('|'。join(searchfor))”
2赞
The Dan
2/12/2021
在这种情况下,我知道我们使用“|”表示 OR,我们如何使用 AND??
105赞
l'L'l
10/27/2014
#2
您可以使用以下命令单独使用正则表达式模式: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
评论
3赞
JacoSolari
3/26/2020
如何为AND做?
3赞
James
3/26/2020
@JacoSolari看看这个答案 stackoverflow.com/questions/37011734/......
3赞
JacoSolari
3/26/2020
@James是的,谢谢。为了完成,这里是该答案中投票最多的一句话。df.col.str.contains(r'(?=.*apple)(?=.*banana)',regex=True)
15赞
Grant Shannon
4/2/2020
#3
下面是一个也有效的单行 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
评论
7赞
emremrah
12/21/2020
我照做了,进展顺利,谢谢。df.loc[df.col1.apply(lambda x: True if any(i in x for i in searchfor) else False)]
0赞
Mammatt
12/16/2022
#4
有同样的问题。在不让它太复杂的情况下,您可以在每个条目之间添加,例如作品|
fieldname.str.contains("cat|dog")
评论
0赞
Alexander L. Hayes
12/20/2022
嗨,您好👋,已经提供了此解决方案(stackoverflow.com/a/26578218/12439119),尽量不要重复答案。
评论
pd.Series.str.contains
pd.Series.str.endswith