web-dev-qa-db-ja.com

文字列にリスト内の部分文字列のいずれかが含まれているかどうかをパンダでテストするにはどうすればよいですか?

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()

これを行うためのより良い方法はありますか?

75
ari

1つのオプションは、正規表現|文字を使用して、シリーズ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と共に使用すると、文字どおり各文字と一致します。

146
Alex Riley

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 
33
l'L'l