Python

Filtrado de cadenas de texto en DataFrame con Pandas

En una entrada anterior se explicó cómo filtrar registros en DataFrames de Pandas en base a los valores de los registros. Para lo que se utilizaron ejemplos únicamente numéricos. En los comentarios de la entrada varios lectores preguntasteis cómo hacer el filtrado de cadenas de texto en DataFrame, ya que esta es una tarea también habitual.

En la entrada de hoy nos vamos a centrar en explicar cómo realizar operaciones de filtrado en base al contenido de las cadenas de texto. Para lo que utilizaremos principalmente el método str.contains() que existe en las series de Pandas.

Conjunto de datos de ejemplo

Al igual que en la entrada anterior vamos a utilizar el conjunto de datos de exoplanetas que se puede encontrar en la librería Seaborn. Un conjunto de datos que contiene en una de las series cadenas de texto. La importación del conjunto de datos se puede realizar con el siguiente código.

import seaborn as sb

planets = sb.load_dataset('planets')
planets.head()
            method  number  orbital_period   mass  distance  year
0  Radial Velocity       1         269.300   7.10     77.40  2006
1  Radial Velocity       1         874.774   2.21     56.95  2008
2  Radial Velocity       1         763.000   2.60     19.84  2011
3  Radial Velocity       1         326.030  19.40    110.62  2007
4  Radial Velocity       1         516.220  10.50    119.47  2009

La columna method contiene el nombre de los métodos mediante los que se descubrió cada uno de los exoplanetas. Podemos comprobar fácilmente que existen 10 métodos y ver estos con el siguiente código.

planets.method.unique()
['Radial Velocity' 'Imaging' 'Eclipse Timing Variations' 'Transit'
 'Astrometry' 'Transit Timing Variations' 'Orbital Brightness Modulation'
 'Microlensing' 'Pulsar Timing' 'Pulsation Timing Variations']

Buscar que contiene una cadena literal

En primer lugar, se pueden buscar los registros que contengan literalmente la cadena de texto que deseamos. Para lo que se puede utilizar el operador igualdad (==). Por ejemplo, para buscar los planetas que han sido descubiertos mediante el método “Pulsar Timing” se puede usar.

planets[planets.method == 'Pulsar Timing']
            method  number  orbital_period  mass  distance  year
941  Pulsar Timing       3       25.262000   NaN       NaN  1992
942  Pulsar Timing       3       66.541900   NaN       NaN  1992
943  Pulsar Timing       3       98.211400   NaN       NaN  1994
944  Pulsar Timing       1    36525.000000   NaN       NaN  2003
945  Pulsar Timing       1        0.090706   NaN    1200.0  2011

En este caso es necesario indicar el nombre de forma exacta, si nos equivocamos el código anterior nos devolverá un DataFrame vacío.

Buscar cadenas de texto con una subcadena

Ampliando el ejemplo anterior, puede ser interesante localizar los planetas descubiertos mediante los métodos que contengan “Pulsa”. Conociendo los valores se puede hacer con el operador igualdad indicando que contenga una cadena u otra. Pero en un caso genérico esta no es una buena aproximación. La solución para esto es utilizar el método str.contains() como se muestra en el siguiente ejemplo.

planets[planets.method.str.contains('Pulsa')]
                          method  number  orbital_period  mass  distance  year
941                Pulsar Timing       3       25.262000   NaN       NaN  1992
942                Pulsar Timing       3       66.541900   NaN       NaN  1992
943                Pulsar Timing       3       98.211400   NaN       NaN  1994
944                Pulsar Timing       1    36525.000000   NaN       NaN  2003
945                Pulsar Timing       1        0.090706   NaN    1200.0  2011
958  Pulsation Timing Variations       1     1170.000000   NaN       NaN  2007

En dónde se han obtenido los cinco planetas de que se han descubierto mediante “Pulsar Timing” y el que se ha descubierto mediante “Pulsation Timing Variations”. Si queremos buscar los que tiene la cadena “Timing” reemplazando una cadena por otra.

Ignorar diferencias entre mayúsculas y minúsculas

Por defecto el método str.contains() diferencia entre mayúsculas y minúsculas, por lo que si escribimos “pulsa” en lugar de “Pulsa” se obtendremos una cadena vacía.

planets[planets.method.str.contains('pulsa')]

Para evitar esto se puede igualar la opción case a falso para que ignore la diferencias entre mayúsculas y minúsculas.

planets[planets.method.str.contains('pulsa', case=False)]
                          method  number  orbital_period  mass  distance  year
941                Pulsar Timing       3       25.262000   NaN       NaN  1992
942                Pulsar Timing       3       66.541900   NaN       NaN  1992
943                Pulsar Timing       3       98.211400   NaN       NaN  1994
944                Pulsar Timing       1    36525.000000   NaN       NaN  2003
945                Pulsar Timing       1        0.090706   NaN    1200.0  2011
958  Pulsation Timing Variations       1     1170.000000   NaN       NaN  2007

Buscar más de una subcadena

Si queremos buscar más de una subcadena se puede utilizar | para separar las cadenas a buscar. En este caso lo que se obtiene todos los registros que contenga una u otra subcadena. Por ejemplo, se pueden buscar los métodos que contenga “Pulsar” u “Orbital” en sus nombres.

planets[planets.method.str.contains('Pulsar|Orbital')]
                            method  number  orbital_period  mass  distance  year
787  Orbital Brightness Modulation       2        0.240104   NaN    1180.0  2011 
788  Orbital Brightness Modulation       2        0.342887   NaN    1180.0  2011 
792  Orbital Brightness Modulation       1        1.544929   NaN       NaN  2013 
941                  Pulsar Timing       3       25.262000   NaN       NaN  1992 
942                  Pulsar Timing       3       66.541900   NaN       NaN  1992 
943                  Pulsar Timing       3       98.211400   NaN       NaN  1994 
944                  Pulsar Timing       1    36525.000000   NaN       NaN  2003 
945                  Pulsar Timing       1        0.090706   NaN    1200.0  2011 

Expresiones regulares

El método str.contains() puede emplearse también expresiones regulares, lo que ofrece múltiples posibilidades.

planets[planets.method.str.contains('Pulsa?', regex=True)]
                          method  number  orbital_period  mass  distance  year
941                Pulsar Timing       3       25.262000   NaN       NaN  1992
942                Pulsar Timing       3       66.541900   NaN       NaN  1992
943                Pulsar Timing       3       98.211400   NaN       NaN  1994
944                Pulsar Timing       1    36525.000000   NaN       NaN  2003
945                Pulsar Timing       1        0.090706   NaN    1200.0  2011
958  Pulsation Timing Variations       1     1170.000000   NaN       NaN  2007

Conclusiones

En esta entrada se ha visto cómo se puede utilizar el método str.contains() para realizar el filtrado de cadenas de texto en DataFrame con Pandas.

Imágenes: Pixabay (Nicole)

¿Te ha parecido de utilidad el contenido?

Daniel Rodríguez

Share
Published by
Daniel Rodríguez
Tags: Pandas

Recent Posts

Cómo calcular el tamaño de la muestra para encuestas

Calcular adecuadamente el tamaño de la muestra es una parte esencial en el diseño de…

2 días ago

Curiosidad: El origen del análisis exploratorio de datos y el papel de John Tukey

Hoy en día, cuando pensamos en ciencia de datos, lo primero que nos viene a…

7 días ago

Cómo extender el tamaño de un disco en Rocky Linux 9 usando growpart y LVM

Ampliar el espacio de almacenamiento en un sistema Linux es una tarea habitual y crítica…

1 semana ago

Nuevo video: cómo activar copiar y pegar en VirtualBox fácilmente

¿Sabías que puedes copiar y pegar texto, archivos o imágenes entre tu sistema operativo principal…

2 semanas ago

Nuevo video: Leer y guardar archivos Excel y CSV en Python

Hoy publicamos un nuevo video en el canal de YouTube de Analytics Lane basado en…

2 semanas ago

Nuevo video en YouTube: Trabajando con archivos JSON en Python

En el canal de YouTube de Analytics Lane hemos publicado un nuevo video donde explicamos…

3 semanas ago

This website uses cookies.