2014-10-26 588 views
24

是否有任何函数可能等效于df.isin()df[col].str.contains()的组合?pandas:测试字符串是否包含列表中的一个子字符串

例如,说我有一系列 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() 

有没有更好的方式来做到这一点?

回答

47

一种方法是使用正则表达式|字符来尝试匹配系列s(仍使用str.contains)中的单词中的每个子字符串。

您可以通过|加盟searchfor的话构建正则表达式:

>>> searchfor = ['og', 'at'] 
>>> s[s.str.contains('|'.join(searchfor))] 
0 cat 
1 hat 
2 dog 
3 fog 
dtype: object 

正如@AndyHayden在下面的评论中指出,照顾,如果你的子有特殊字符,如$^要从字面上匹配。这些字符在正则表达式的上下文中具有特定的含义,并会影响匹配。在这个新的列表将与str.contains使用时,每一个字符地匹配

>>> import re 
>>> matches = ['$money', 'x^y'] 
>>> safe_matches = [re.escape(m) for m in matches] 
>>> safe_matches 
['\\$money', 'x\\^y'] 

的字符串:

你可以让你通过子逃避非字母数字字符更安全的清单,re.escape

+4

也许很好添加此链接http://pandas.pydata.org/pandas-docs/stable/text.html#splitting-and-replacing-strings了。从熊猫0.15开始,字符串操作更容易 – goofd 2014-10-26 21:19:09

+4

有一点你必须注意的是,如果searchfor中的字符串有特殊的正则表达式字符(你可以[用re.escape映射](http://stackoverflow.com/questions)/280435 /逸出正则表达式串合蟒))。 – 2014-10-26 21:24:56

+0

@AndyHayden谢谢你,我已经改进了我的答案,将这个复杂因素考虑在内。 – 2014-10-26 21:42:47

11

您可以使用OR (|)正则表达式模式单独使用str.contains

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 
相关问题