web-dev-qa-db-ja.com

pandas dataframe str.contains()AND operation

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個の異なる単語(ブドウ、スイカ、ベリー、オレンジなど)を含む文字列を取得したい

17
Aerin

次のようにできます。

df[(df['col_name'].str.contains('Apple')) & (df['col_name'].str.contains('banana'))]
13
flyingmeatball
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
14
Alexander

正規表現式で行うこともできます:

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

その後、あなたは自分のものを動的に行うことができます。

8
Anzel

これは動作します

df.col.str.contains(r'(?=.*Apple)(?=.*banana)',regex=True)
5
Charan Reddy

あなたが文の少なくとも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
2
Siraj S.

ネイティブメソッドのみを使用し、正規表現の記述を避けたい場合は、ラムダを使用しないベクトル化バージョンを以下に示します。

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]
2
Sergey Zakharov

この正規表現を試してください

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
1
pmaniyan

大きなリストのすべての可能性を列挙するのは面倒です。より良い方法は、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
1
pault