文字列がリスト内のサブ文字列の1つをパンダで含むかどうかをテストする方法は?


119

df.isin()andの組み合わせに相当する関数はあり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()

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


@unutbu説明されているソリューションは、を使用するよりも効率的ですpd.Series.str.contains。パフォーマンスに問題がある場合は、調査する価値があるかもしれません。
2018年

複数のキーワード/正規表現を使用した部分的な文字列検索については、この回答をチェックすることを強くお勧めします(「複数の部分文字列検索」小見出しまでスクロールします)。
cs95

回答:


219

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ます。


4
このリンクpandas.pydata.org/pandas-docs/stable/…も追加するとよいでしょう。パンダ0.15から始まって、文字列操作がさらに簡単です
goofd

6
注意が必要なことの1つは、searchforの文字列に特別な正規表現文字が含まれている場合です(re.escapeでマップできます)。
アンディヘイデン

@AndyHaydenありがとう、この複雑さを考慮に入れるように回答を改善しました。
Alex Riley

あなたのメソッドが "str.startswith( '|' .join(searchfor))"で機能しない理由がわかりません
Doo Hyun Shin

48

次を使用str.containsして正規表現パターンで単独で使用できますOR (|)

s[s.str.contains('og|at')]

または、シリーズをdataframethenに追加して、次のように使用できますstr.contains

df = pd.DataFrame(s)
df[s.str.contains('og|at')] 

出力:

0 cat
1 hat
2 dog
3 fog 

ANDの方法
JacoSolari

1
@JacoSolariこの回答のチェックアウトstackoverflow.com/questions/37011734/...
ジェームズ・

1
@ジェームスはい、ありがとう。ここでの完了は、その回答の中で最も支持されているワンライナーです。df.col.str.contains(r'(?=.*apple)(?=.*banana)',regex=True)
JacoSolari

1

これも機能する1行のラムダです。

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.