df (Pandas Dataframe) tiene tres filas.
some_col_name "apple is delicious" "banana is delicious" "apple and banana both are delicious"
df.col_name.str.contains("apple|banana")
Atrapará todas las filas:
"apple is delicious", "banana is delicious", "apple and banana both are delicious".
¿Cómo aplico el operador AND en el método str.contains, de modo que solo tome cuerdas que contengan AMBAS manzanas y bananos?
"apple and banana both are delicious"
Me gustaría agarrar cuerdas que contienen 10-20 palabras diferentes (uva, sandía, baya, naranja, …, etc.)
Puedes hacerlo de la siguiente manera:
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
También puedes hacerlo en el estilo de expresión regex:
df[df['col_name'].str.contains(r'^(?=.*apple)(?=.*banana)')]
Luego, puede construir su lista de palabras en una cadena de expresiones regulares como:
base = r'^{}' expr = '(?=.*{})' words = ['apple', 'banana', 'cat'] # example base.format(''.join(expr.format(w) for w in words))
renderizará:
'^(?=.*apple)(?=.*banana)(?=.*cat)'
Entonces puedes hacer tus cosas dinámicamente.
Esto funciona
df.col.str.contains(r'(?=.*apple)(?=.*banana)',regex=True)
Si desea capturar en el mínimo al menos dos palabras en la oración, tal vez esto funcione (tomando la sugerencia de @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)))]
salida:
col 2 apple and banana both are delicious
Si tiene más de dos palabras para capturar que están separadas por comas ‘,’ entonces agréguelas a la lista de conectores y modifique la segunda condición de todas a cualquiera
df[df.col.apply(lambda sentence: (any(word in sentence for word in target)) & (any(connector in sentence for connector in connector_list)))]
salida:
col 2 apple and banana both are delicious 3 orange,banana and apple all are delicious
Prueba este regex
apple.*banana|banana.*apple
El código es:
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')]
Salida
ID String_Col 2 3 apple and banana both are delicious
Enumerar todas las posibilidades para listas grandes es engorroso. Una mejor manera es utilizar reduce()
y el operador Y ( &
) a nivel de bits .
Por ejemplo, considere el siguiente 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
Supongamos que queremos buscar todo lo siguiente:
targets = ['apple', 'banana', 'strawberry']
Podemos hacer:
#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