2014-10-26 809 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 
相關問題