Tengo un DataFrame
con 4 columnas de las cuales 2 contienen valores de cadena. Me preguntaba si había una manera de seleccionar filas en función de una coincidencia de cadena parcial contra una columna en particular.
En otras palabras, una función o función lambda que haría algo como
re.search(pattern, cell_in_question)
devolviendo un booleano. Estoy familiarizado con la sintaxis de, df[df['A'] == "hello world"]
pero parece que no puedo encontrar una manera de hacer lo mismo con una coincidencia de cadena parcial, por ejemplo 'hello'
.
¿Alguien podría señalarme en la dirección correcta?
df[df['A'].str.contains("Hello|Britain")]
.str.contains
para usar.query()
api ?df[df['value'].astype(str).str.contains('1234.+')]
para filtrar columnas que no son de tipo cadena.Probé la solución propuesta arriba:
y recibí un error:
puedes transformar los valores de NA en
False
, así:fuente
df[df['A'].astype(str).str.contains("Hello|Britain")]
funcionó bienEsta publicación está destinada a lectores que quieran
isin
)... y me gustaría saber más sobre qué métodos deberían preferirse sobre otros.
(PD: he visto muchas preguntas sobre temas similares, pensé que sería bueno dejar esto aquí).
Búsqueda básica de subcadenas
str.contains
se puede usar para realizar búsquedas de subcadenas o búsquedas basadas en expresiones regulares. La búsqueda por defecto es basada en expresiones regulares a menos que la desactive explícitamente.Aquí hay un ejemplo de búsqueda basada en expresiones regulares,
A veces, la búsqueda de expresiones regulares no es necesaria, así que especifique
regex=False
deshabilitarla.En cuanto al rendimiento, la búsqueda de expresiones regulares es más lenta que la búsqueda de subcadenas:
Evite usar la búsqueda basada en expresiones regulares si no la necesita.
Direccionamiento
ValueError
sA veces, realizar una búsqueda de subcadenas y filtrar el resultado dará como resultado
Esto generalmente se debe a datos mixtos o NaNs en su columna de objeto,
Cualquier cosa que no sea una cadena no puede tener métodos de cadena aplicados, por lo que el resultado es NaN (naturalmente). En este caso, especifique
na=False
ignorar datos que no sean cadenas,Búsqueda de subcadenas múltiples
Esto se logra más fácilmente a través de una búsqueda de expresiones regulares utilizando la tubería OR de expresiones regulares.
También puede crear una lista de términos, luego unirse a ellos:
A veces, es aconsejable escapar de sus términos en caso de que tengan caracteres que puedan interpretarse como metacaracteres regex . Si sus términos contienen alguno de los siguientes caracteres ...
Luego, deberás usar
re.escape
para escapar de ellos:re.escape
tiene el efecto de escapar de los caracteres especiales para que sean tratados literalmente.Palabra (s) completa (s)
De forma predeterminada, la búsqueda de subcadena busca la subcadena / patrón especificado, independientemente de si es palabra completa o no. Para que solo coincidan las palabras completas, tendremos que utilizar expresiones regulares aquí, en particular, nuestro patrón deberá especificar los límites de las palabras (
\b
).Por ejemplo,
Ahora considere
v / s
Búsqueda de palabras completas múltiples
Similar al anterior, excepto que agregamos un límite de palabra (
\b
) al patrón unido.Donde se
p
ve así,Una gran alternativa: ¡Usar las comprensiones de la lista !
¡Porque tú puedes! ¡Y deberías! Por lo general, son un poco más rápidos que los métodos de cadena, porque los métodos de cadena son difíciles de vectorizar y generalmente tienen implementaciones en bucle.
En vez de,
Utilice el
in
operador dentro de una lista de comp.En vez de,
Use
re.compile
(para almacenar en caché su expresión regular) +Pattern.search
dentro de una lista de comp,Si "col" tiene NaN, entonces en lugar de
Utilizar,
Más opciones para la coincidencia parcial de la secuencia:
np.char.find
,np.vectorize
,DataFrame.query
.Además de una
str.contains
lista de comprensiones, también puede usar las siguientes alternativas.np.char.find
Solo admite búsquedas de subcadenas (lectura: sin expresiones regulares).
np.vectorize
Este es un contenedor alrededor de un bucle, pero con una sobrecarga menor que la mayoría de los
str
métodos pandas .Posibles soluciones Regex:
DataFrame.query
Admite métodos de cadena a través del motor de Python. Esto no ofrece beneficios de rendimiento visibles, pero es útil saber si necesita generar dinámicamente sus consultas.
Se puede encontrar más información
query
y unaeval
familia de métodos en Evaluación de expresión dinámica en pandas usando pd.eval () .Precedencia de uso recomendada
str.contains
, por su simplicidad y facilidad de manejo de NaNs y datos mixtosnp.vectorize
df.query
fuente
any(needle in haystack for needling in ['foo', 'bar'] and haystack in (df['col'], df['col2']))
y las variaciones que probé con todos los estranguladores (se quejaany()
y con razón ... Pero el documento no es muy claro sobre cómo hacer esa consulta.)df[['col1', 'col2']].apply(lambda x: x.str.contains('foo|bar')).any(axis=1)
Si alguien se pregunta cómo realizar un problema relacionado: "Seleccionar columna por cadena parcial"
Utilizar:
Y para seleccionar filas por coincidencia parcial de cadenas, pase
axis=0
al filtro:fuente
df.loc[:, df.columns.str.contains('a')]
df.filter(like='a')
Nota rápida: si desea hacer una selección basada en una cadena parcial contenida en el índice, intente lo siguiente:
fuente
Digamos que tiene lo siguiente
DataFrame
:Siempre puede usar el
in
operador en una expresión lambda para crear su filtro.El truco aquí es usar la
axis=1
opciónapply
para pasar elementos a la función lambda fila por fila, en lugar de columna por columna.fuente
Esto es lo que terminé haciendo para coincidencias parciales de cadenas. Si alguien tiene una forma más eficiente de hacerlo, hágamelo saber.
fuente
El uso de contiene no funcionó bien para mi cadena con caracteres especiales. Encontrar funcionó sin embargo.
fuente
Hay respuestas antes de esto que cumplen la función solicitada, de todos modos me gustaría mostrar la forma más general:
De esta forma, le permite obtener la columna que busca, independientemente de la forma en que se escriba.
(Obviamente, debe escribir la expresión de expresión regular adecuada para cada caso)
fuente
Tal vez desee buscar texto en todas las columnas del marco de datos de Pandas, y no solo en el subconjunto de ellas. En este caso, el siguiente código será de ayuda.
Advertencia. Este método es relativamente lento, aunque conveniente.
fuente
Si necesita hacer una búsqueda sin distinción entre mayúsculas y minúsculas para una cadena en una columna de marco de datos de pandas:
fuente