df(Pandas Dataframe)には3つの行があります。
_some_col_name
"Apple is delicious"
"banana is delicious"
"Apple and banana both are delicious"
_
df.col_name.str.contains("Apple|banana")
すべての行をキャッチします。
_"Apple is delicious",
"banana is delicious",
"Apple and banana both are delicious".
_
Str.containsメソッドにAND演算子を適用するには、BOTH Apple&banana?
_"Apple and banana both are delicious"
_
10〜20個の異なる単語(ブドウ、スイカ、ベリー、オレンジなど)を含む文字列を取得したい
次のようにできます。
df[(df['col_name'].str.contains('Apple')) & (df['col_name'].str.contains('banana'))]
df = pd.DataFrame({'col': ["Apple is delicious",
"banana is delicious",
"Apple and banana both are delicious"]})
targets = ['Apple', 'banana']
# Any Word from `targets` are present in sentence.
>>> df.col.apply(lambda sentence: any(Word in sentence for Word in targets))
0 True
1 True
2 True
Name: col, dtype: bool
# All words from `targets` are present in sentence.
>>> df.col.apply(lambda sentence: all(Word in sentence for Word in targets))
0 False
1 False
2 True
Name: col, dtype: bool
正規表現式で行うこともできます:
df[df['col_name'].str.contains(r'^(?=.*Apple)(?=.*banana)')]
その後、次のように単語のリストを正規表現文字列に作成できます。
base = r'^{}'
expr = '(?=.*{})'
words = ['Apple', 'banana', 'cat'] # example
base.format(''.join(expr.format(w) for w in words))
レンダリングします:
'^(?=.*Apple)(?=.*banana)(?=.*cat)'
その後、あなたは自分のものを動的に行うことができます。
これは動作します
df.col.str.contains(r'(?=.*Apple)(?=.*banana)',regex=True)
あなたが文の少なくとも2つの単語をキャッチしたい場合は、おそらくこれが動作します(@Alexanderからヒントを取ります):
target=['Apple','banana','grapes','orange']
connector_list=['and']
df[df.col.apply(lambda sentence: (any(Word in sentence for Word in target)) & (all(connector in sentence for connector in connector_list)))]
出力:
col
2 Apple and banana both are delicious
コンマ「 '」で区切られた3つ以上の単語をキャッチする場合は、それをconnector_listに追加し、2番目の条件をallからanyに変更します
df[df.col.apply(lambda sentence: (any(Word in sentence for Word in target)) & (any(connector in sentence for connector in connector_list)))]
出力:
col
2 Apple and banana both are delicious
3 orange,banana and Apple all are delicious
ネイティブメソッドのみを使用し、正規表現の記述を避けたい場合は、ラムダを使用しないベクトル化バージョンを以下に示します。
targets = ['Apple', 'banana', 'strawberry']
fruit_masks = (df['col'].str.contains(string) for string in targets)
combined_mask = np.vstack(fruit_masks).all(axis=0)
df[combined_mask]
この正規表現を試してください
Apple.*banana|banana.*Apple
コードは:
import pandas as pd
df = pd.DataFrame([[1,"Apple is delicious"],[2,"banana is delicious"],[3,"Apple and banana both are delicious"]],columns=('ID','String_Col'))
print df[df['String_Col'].str.contains(r'Apple.*banana|banana.*Apple')]
出力
ID String_Col
2 3 Apple and banana both are delicious
大きなリストのすべての可能性を列挙するのは面倒です。より良い方法は、reduce()
と bitwise AND 演算子(&
)。
たとえば、次のDataFrameを考えます。
df = pd.DataFrame({'col': ["Apple is delicious",
"banana is delicious",
"Apple and banana both are delicious",
"i love Apple, banana, and strawberry"]})
# col
#0 Apple is delicious
#1 banana is delicious
#2 Apple and banana both are delicious
#3 i love Apple, banana, and strawberry
次のすべてを検索するとします。
targets = ['Apple', 'banana', 'strawberry']
我々はできる:
#from functools import reduce # needed for python3
print(df[reduce(lambda a, b: a&b, (df['col'].str.contains(s) for s in targets))])
# col
#3 i love Apple, banana, and strawberry