¿Cómo probar si una cadena contiene una de las subcadenas de una lista, en pandas?

Resuelto ari asked hace 10 años • 4 respuestas

¿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 scontiene 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?

ari avatar Oct 27 '14 03:10 ari
Aceptado

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 searchforcon |:

>>> 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.

Alex Riley avatar Oct 26 '2014 20:10 Alex Riley

Puedes usarlo str.containssolo con un patrón de expresiones regulares usando OR (|):

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

O podrías agregar la serie a y dataframeluego usar str.contains:

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

Producción:

0 cat
1 hat
2 dog
3 fog 
l'L'l avatar Oct 26 '2014 21:10 l'L'l