¿Cómo probar si una cadena contiene una de las subcadenas de una lista? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

¿Hay 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 saber todos los lugares donde s contiene cualquiera de ['og', 'at'], me gustaría obtener todo menos mascotas.

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?

Author: TylerH, 2014-10-26

2 answers

Una opción es usar el carácter regex | para tratar de hacer coincidir cada una de las subcadenas en las palabras de su Serie s (aún usando str.contains).

Puede construir la expresión regular uniendo las palabras en searchfor con |:

>>> searchfor = ['og', 'at']
>>> s[s.str.contains('|'.join(searchfor))]
0    cat
1    hat
2    dog
3    fog
dtype: object

Como @AndyHayden señaló en los comentarios a continuación, tenga cuidado si sus subcadenas tienen caracteres especiales como $ y ^ que desea que coincidan literalmente. Estos caracteres tienen significados específicos en el contexto de expresiones regulares y afectará a 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.

 85
Author: Alex Riley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-28 20:42:50

Puedes usar str.contains solo con un patrón de expresiones regulares usando OR (|):

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

O puede agregar la serie a un dataframe y luego usar str.contains:

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

Salida:

0 cat
1 hat
2 dog
3 fog 
 25
Author: l'L'l,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-26 21:33:30