Búsqueda de sitios web

Uso conjunto de Pandas y SQL para el análisis de datos


En este tutorial, exploraremos cuándo y cómo se puede integrar la funcionalidad SQL dentro del marco de Pandas, así como sus limitaciones.

SQL, o lenguaje de consulta estructurado, ha sido durante mucho tiempo la herramienta de referencia para la gestión de datos, pero hay ocasiones en las que se queda corto y requiere la potencia y flexibilidad de una herramienta como Python. Python, un lenguaje de programación versátil y multipropósito, se destaca en el acceso, extracción, manipulación y exploración de datos de bases de datos relacionales. Dentro de Python, la biblioteca de código abierto Pandas está diseñada específicamente para la manipulación y análisis de datos.

En este tutorial, exploraremos cuándo y cómo se puede integrar la funcionalidad SQL dentro del marco de Pandas, así como sus limitaciones.

La pregunta principal que quizás te hagas ahora mismo es...

¿Por qué utilizar ambos?

La razón radica en la legibilidad y la familiaridad: en ciertos casos, especialmente en flujos de trabajo complejos, las consultas SQL pueden ser mucho más claras y fáciles de leer que el código Pandas equivalente. Esto es particularmente cierto para aquellos que comenzaron a trabajar con datos en SQL antes de hacer la transición a Pandas.

Además, dado que la mayoría de los datos se originan en bases de datos, SQL (al ser el idioma nativo de estas bases de datos) ofrece una ventaja natural. Esta es la razón por la que muchos profesionales de datos, en particular los científicos de datos, a menudo integran SQL y Python (específicamente, Pandas) dentro del mismo canal de datos para aprovechar las fortalezas de cada uno.

Para ver la legibilidad de SQL en acción, usemos el siguiente archivo csv pokedex pokemon gen1.

Imaginemos que queremos ordenar el DataFrame por la columna "Total" en orden ascendente y mostrar los 5 primeros. Ahora podemos comparar cómo realizar la misma acción tanto con Pandas como con SQL.

Usando Pandas con Python:

data[["#", "Name", "Total"]].sort_values(by="Total", ascending=True).head(5)

Usando SQL:

SELECT 
     "#", 
     Name, 
     Total
FROM data
ORDER  BY Total
LIMIT 5

¿Ves lo diferentes que son ambos verdad? Pero… ¿cómo podemos combinar ambos lenguajes dentro de nuestro entorno de trabajo con Python?

¡La solución es usar PandaSQL!

Usando PandaSQL

Pandas es una potente biblioteca Python de análisis y manipulación de datos de código abierto. PandaSQL permite el uso de sintaxis SQL para consultar Pandas DataFrames. Para las personas nuevas en Pandas, PandaSQL intenta hacer que la manipulación y limpieza de datos sea más familiar. Puede utilizar PandaSQL para consultar Pandas DataFrames utilizando la sintaxis SQL.

Echemos un vistazo.

Primero, necesitamos instalar PandaSQL:

pip install pandasql

Luego (como siempre), importamos los paquetes requeridos:

from pandasql import sqldf

Aquí, importamos directamente la función sqldf de PandaSQL, que es esencialmente la característica principal de la biblioteca. Como sugiere el nombre, sqldf le permite consultar DataFrames usando la sintaxis SQL.

sqldf(query_string, env=None)

En este contexto, query_string es un parámetro obligatorio que acepta una consulta SQL en formato de cadena. El parámetro env, opcional y rara vez utilizado, se puede establecer en locals() o globals(), habilitando sqldf para acceder a variables desde el alcance especificado en su entorno Python.
Más allá de esta función, PandaSQL también incluye dos conjuntos de datos básicos integrados que se pueden cargar con funciones sencillas: load_births() y load_meat(). De esta manera, tendrás algunos datos ficticios con los que jugar integrados.

Así que ahora, si queremos ejecutar la consulta SQL anterior dentro de nuestro cuaderno Python Jupyter, sería algo como lo siguiente:

from pandasql import sqldf
import pandas as pd

sqldf('''
     SELECT "#", Name, Total
     FROM data
     ORDER  BY Total
     LIMIT 5''')

La función sqldf devuelve el resultado de una consulta como un Pandas DataFrame.

¿Cuándo debemos usarlo?

La biblioteca pandasql permite la manipulación de datos utilizando el lenguaje de consulta de datos (DQL) de SQL, proporcionando un enfoque familiar basado en SQL para interactuar con datos en Pandas DataFrames.

Con pandasql, puede ejecutar consultas directamente en su conjunto de datos, lo que permite una recuperación, filtrado, clasificación, agrupación, unión y agregación eficientes de datos.

Además, admite la realización de operaciones matemáticas y lógicas, lo que la convierte en una poderosa herramienta para usuarios expertos en SQL que trabajan con datos en Python.

PandaSQL está limitado al subconjunto del lenguaje de consulta de datos (DQL) de SQL, lo que significa que no admite la modificación de tablas o datos: acciones como ACTUALIZAR, INSERT o DELETE no están disponibles.

Además, dado que PandaSQL se basa en la sintaxis SQL, específicamente SQLite, es esencial tener en cuenta las peculiaridades específicas de SQLite que pueden afectar el comportamiento de las consultas.

Comparando PandasSQL y SQL

Esta sección demuestra cómo se pueden utilizar PandaSQL y Pandas para lograr resultados similares, ofreciendo comparaciones lado a lado para resaltar sus respectivos enfoques.

Generando múltiples tablas

Generemos subconjuntos de datos a partir de un conjunto de datos más grande, creando tablas como tipos, legendarios, generaciones y características. Usando PandaSQL, podemos especificar consultas SQL para seleccionar columnas específicas, lo que facilita la extracción de los datos exactos que queremos.

Usando PandaSQL:

types = sqldf('''
     SELECT "#", Name, "Type 1", "Type 2"
     FROM data''')

legendaries = sqldf('''
     SELECT "#", Name, Legendary
     FROM data''')

generations = sqldf('''
     SELECT "#", Name, Generation
     FROM data''')

features = sqldf('''
     SELECT "#", Name, Total, HP, Attack, Defense, "Sp. Atk", "Sp. Def","Speed"
     FROM data''')

Aquí, PandaSQL permite una sintaxis de selección limpia basada en SQL que puede resultar intuitiva para los usuarios familiarizados con las bases de datos relacionales. Es particularmente útil si la selección de datos implica condiciones complejas o funciones SQL.

Usando Python puro:

# Selecting columns for types
types = data[['#', 'Name', 'Type 1', 'Type 2']]

# Selecting columns for legendaries
legendaries = data[['#','Name', 'Legendary']]

# Selecting columns for generations
generations = data[['#','Name', 'Generation']]

# Selecting columns for features
features = data[['#','Name', 'Total', 'HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed']]

En Python puro, logramos el mismo resultado simplemente especificando los nombres de las columnas entre corchetes. Si bien esto es eficaz para la selección de columnas sencilla, puede resultar menos legible con condiciones de filtrado o agrupación más complejas, donde la sintaxis de estilo SQL puede ser más natural.

Realizar JOIN

Las uniones son una forma poderosa de combinar datos de múltiples fuentes basadas en columnas comunes, y tanto PandaSQL como Pandas lo admiten.

Primero, PandaSQL:

types_features = sqldf('''
     SELECT
       t1.*,
       t2.Total,
       t2.HP,
       t2.Attack,
       t2.Defense,
       t2."Sp. Atk",
       t2."Sp. Def",
       t2."Speed"
     FROM types AS t1
     LEFT JOIN features AS t2
       ON  t1."#" = t2."#"
       AND t1.Name = t2.Name
''')

Usando SQL, este LEFT JOIN combina tipos y características basadas en valores coincidentes en las columnas # y Nombre. Este enfoque es simple para los usuarios de SQL, con una sintaxis clara para seleccionar columnas específicas y combinar datos de varias tablas.

En Python puro:

# Performing a left join between `types` and `features` on the columns "#" and "Name"
types_features = types.merge(
   features,
   on=['#', 'Name'],
   how='left'
)

types_features

En Python puro, logramos el mismo resultado usando la función merge(), especificando on para columnas coincidentes y how='left' para realizar una unión izquierda. Pandas facilita la fusión en varias columnas y ofrece flexibilidad para especificar tipos de unión. Sin embargo, la sintaxis de combinación de estilo SQL puede ser más legible cuando se trabaja con tablas más grandes o se realizan combinaciones más complejas.

Consulta personalizada

En este ejemplo, recuperamos los 5 registros principales según "Defensa", ordenados en orden descendente.

PandaSQL:

top_5_defense = sqldf('''
     SELECT
       Name, Defense
     FROM features
     ORDER BY Defense DESC
     LIMIT 5
''')

La consulta SQL ordena las funciones por la columna Defensa en orden descendente y limita el resultado a las 5 entradas principales. Este enfoque es directo, especialmente para usuarios de SQL, con las palabras clave ORDER BY y LIMIT que dejan claro lo que hace la consulta.

Y en Python puro:

top_5_defense = features[['Name', 'Defense']].sort_values(by='Defense', ascending=False).head(5)

Usando solo Python, logramos el mismo resultado usando sort_values() para ordenar por Defensa y luego head(5) para limitar la salida. Pandas proporciona una sintaxis flexible e intuitiva para ordenar y seleccionar registros, aunque el enfoque SQL aún puede resultar más familiar para quienes trabajan habitualmente con bases de datos.

Conclusión

En este tutorial, examinamos cómo y cuándo combinar la funcionalidad SQL con Pandas puede ayudar a producir código más limpio y eficiente. Cubrimos la configuración y el uso de la biblioteca PandaSQL, junto con sus limitaciones, y analizamos ejemplos populares para comparar el código PandaSQL con el código Pandas Python equivalente.

Al comparar estos enfoques, puede ver que PandaSQL es útil para usuarios nativos de SQL o escenarios con consultas complejas, mientras que el código nativo de Pandas puede ser más pitónico e integrado para aquellos acostumbrados a trabajar en Python.

Puede consultar todo el código que se muestra aquí en el siguiente Jupyter Notebook