¿Cómo probar si una cadena contiene una de las subcadenas de una lista, en pandas?
¿Existe alguna función que sea equivalente a una combinación de df.isin()
y df[col].str.contains()
?
Por ejemplo, digamos que tengo la serie
s = pd.Series(['cat','hat','dog','fog','pet'])
y quiero encontrar todos los lugares donde s
contiene alguno de ellos ['og', 'at']
, me gustaría obtener todo menos "mascota".
Tengo una solución, pero es bastante poco elegante:
searchfor = ['og', 'at']
found = [s.str.contains(x) for x in searchfor]
result = pd.DataFrame[found]
result.any()
¿Hay una mejor manera de hacer esto?
Una opción es simplemente usar el |
carácter de expresión regular para intentar hacer coincidir cada una de las subcadenas de las palabras de su serie s
(aún usando str.contains
).
Puedes construir la expresión regular uniendo las palabras searchfor
con |
:
>>> searchfor = ['og', 'at']
>>> s[s.str.contains('|'.join(searchfor))]
0 cat
1 hat
2 dog
3 fog
dtype: object
Como señaló @AndyHayden en los comentarios a continuación, tenga cuidado si sus subcadenas tienen caracteres especiales como $
y ^
con los que desea que coincidan literalmente. Estos caracteres tienen significados específicos en el contexto de expresiones regulares y afectarán la coincidencia.
Puede hacer que su lista de subcadenas sea más segura escapando caracteres no alfanuméricos con re.escape
:
>>> import re
>>> matches = ['$money', 'x^y']
>>> safe_matches = [re.escape(m) for m in matches]
>>> safe_matches
['\\$money', 'x\\^y']
Las cadenas con en esta nueva lista coincidirán literalmente con cada carácter cuando se usen con str.contains
.
Puedes usarlo str.contains
solo con un patrón de expresiones regulares usando OR (|)
:
s[s.str.contains('og|at')]
O podrías agregar la serie a y dataframe
luego usar str.contains
:
df = pd.DataFrame(s)
df[s.str.contains('og|at')]
Producción:
0 cat
1 hat
2 dog
3 fog