Introducción a la visualización de datos en Python con Pandas

I

Introducción

Las personas rara vez pueden ver datos sin procesar e inmediatamente deducir una observación orientada a datos como:

¡La gente en las tiendas tiende a comprar pañales y cerveza en conjunto!

O incluso si usted, como científico de datos, puede leer datos sin procesar, lo más probable es que su inversionista o jefe no pueda.

Para que podamos analizar correctamente nuestros datos, debemos representarlos de una manera tangible y completa. ¡Por eso exactamente utilizamos la visualización de datos!

La pandasbiblioteca ofrece una gran variedad de herramientas que lo ayudarán a lograrlo. En este artículo, veremos paso a paso y cubriremos todo lo que necesita para comenzar con las pandasherramientas de visualización, incluidos gráficos de barras, histogramas, diagramas de área, diagramas de densidad, matrices de dispersión y diagramas de arranque.

Importación de datos

Primero, necesitaremos un pequeño conjunto de datos para trabajar y probar cosas.

Usaré un conjunto de datos de comida india ya que, francamente, la comida india es deliciosa. Puede descargarlo gratis de Kaggle.com . Para importarlo, usaremos el read_csv()método que devuelve un DataFrame. Aquí hay un pequeño fragmento de código, que imprime las primeras cinco y las últimas cinco entradas en nuestro conjunto de datos. Hagamos un intento:

import pandas as pd
menu = pd.read_csv('indian_food.csv')
print(menu)

Ejecutar este código dará como resultado:

               name            state      region ...  course
0        Balu shahi      West Bengal        East ... dessert
1            Boondi        Rajasthan        West ... dessert
2    Gajar ka halwa           Punjab       North ... dessert
3            Ghevar        Rajasthan        West ... dessert
4       Gulab jamun      West Bengal        East ... dessert
..              ...              ...         ... ...     ...
250       Til Pitha            Assam  North East ... dessert
251         Bebinca              Goa        West ... dessert
252          Shufta  Jammu & Kashmir       North ... dessert
253       Mawa Bati   Madhya Pradesh     Central ... dessert
254          Pinaca              Goa        West ... dessert

Si desea cargar datos desde otro formato de archivo, pandasofrece métodos de lectura similares como read_json(). La vista está ligeramente truncada debido a la forma larga de la ingredientsvariable.

Para extraer solo unas pocas columnas seleccionadas, podemos crear un subconjunto del conjunto de datos mediante corchetes y enumerar los nombres de las columnas en las que nos gustaría centrarnos:

import pandas as pd

menu = pd.read_csv('indian_food.csv')
recepies = menu[['name', 'ingredients']]
print(recepies)

Esto produce:

               name                                        ingredients
0        Balu shahi                    Maida flour, yogurt, oil, sugar
1            Boondi                            Gram flour, ghee, sugar
2    Gajar ka halwa       Carrots, milk, sugar, ghee, cashews, raisins
3            Ghevar  Flour, ghee, kewra, milk, clarified butter, su...
4       Gulab jamun  Milk powder, plain flour, baking powder, ghee,...
..              ...                                                ...
250       Til Pitha            Glutinous rice, black sesame seeds, gur
251         Bebinca  Coconut milk, egg yolks, clarified butter, all...
252          Shufta  Cottage cheese, dry dates, dried rose petals, ...
253       Mawa Bati  Milk powder, dry fruits, arrowroot powder, all...
254          Pinaca  Brown rice, fennel seeds, grated coconut, blac...

[255 rows x 2 columns]

Trazar gráficos de barras con pandas

El gráfico de barras clásico es fácil de leer y es un buen punto de partida: visualicemos cuánto tiempo lleva cocinar cada plato.

Pandas se basa en el motor Matplotlib para mostrar los gráficos generados. Así que tendremos que importar el módulo PyPlot de Matplotlib para llamar plt.show()después de que se generen los gráficos.

Primero, importemos nuestros datos. Hay muchos platos en nuestro conjunto de datos, 255 para ser exactos. Esto realmente no encajará en una sola figura mientras se mantenga legible.

Usaremos el head()método para extraer los primeros 10 platos y extraer las variables relevantes para nuestra gráfica. Es decir, queremos extraer el namey cook_timepara cada plato en un nuevo DataFrame llamado name_and_timey truncarlo a los primeros 10 platos:

import pandas as pd
import matplotlib.pyplot as plt

menu = pd.read_csv('indian_food.csv')

name_and_time = menu[['name','cook_time']].head(10)

Ahora usaremos el bar()método para trazar nuestros datos:

DataFrame.plot.bar(x=None, y=None, **kwargs)
  • Los parámetros xy yse corresponden con los ejes X e Y
  • kwargscorresponde a argumentos de palabras clave adicionales que están documentados en DataFrame.plot().

Se pueden pasar muchos parámetros adicionales para personalizar aún más el gráfico, como rotpara la rotación de etiquetas, legendpara agregar una leyenda style, etc.

Muchos de estos argumentos tienen valores predeterminados, la mayoría de los cuales están desactivados. Dado que el rotargumento predeterminado es 90, nuestras etiquetas se rotarán 90 grados. Cambiemos eso a 30 mientras construimos la trama:

name_and_time.plot.bar(x='name',y='cook_time', rot=30)

Y finalmente, llamaremos al show()método desde la instancia de PyPlot para mostrar nuestro gráfico:

plt.show()

Esto generará nuestro gráfico de barras deseado:

Trazado de varias columnas en el eje X del gráfico de barras en Pandas

A menudo, es posible que deseemos comparar dos variables en un gráfico de barras, como cook_timey prep_time. Ambas son variables correspondientes a cada plato y son directamente comparables.

Cambiemos el name_and_timeDataFrame para que también incluya prep_time:

name_and_time = menu[['name','prep_time','cook_time']].head(10)
name_and_time.plot.bar(x='name', rot=30)

Pandas asumió automáticamente que los dos valores numéricos al lado nameestán vinculados a él, por lo que basta con definir el eje X. Cuando se trata de otros DataFrames, es posible que este no sea el caso.

Si necesita definir explícitamente qué otras variables deben trazarse, simplemente puede pasar una lista:

name_and_time.plot.bar(x='name', y=['prep_time','cook_time'], rot=30)

Ejecutar cualquiera de estos dos códigos producirá:

Eso es interesante. Parece que los alimentos que se cocinan más rápido requieren más tiempo de preparación y viceversa. Sin embargo, esto proviene de un subconjunto bastante limitado de datos y esta suposición podría ser incorrecta para otros subconjuntos.

Trazado de gráficos de barras apilados con pandas

Veamos qué plato lleva más tiempo preparar en general. Como queremos tener en cuenta tanto el tiempo de preparación como el tiempo de cocción, los apilaremos uno encima del otro.

Para hacer eso, configuraremos el stackedparámetro a True:

name_and_time.plot.bar(x='name', stacked=True)

Ahora, podemos ver fácilmente qué platos tardan más en prepararse, teniendo en cuenta tanto el tiempo de preparación como el tiempo de cocción.

Personalización de gráficos de barras en Pandas

Si queremos que los gráficos se vean un poco más bonitos, podemos pasar algunos argumentos adicionales al bar()método, como:

  • color– Que define un color para cada uno de los DataFrameatributos de. Puede ser una cadena como 'orange', rgbo un código rgb como #faa005.
  • title – Una cadena o lista que significa el título de la trama.
  • grid – Un valor booleano que indica si las líneas de la cuadrícula son visibles.
  • figsize – Una tupla que indica el tamaño de la parcela en pulgadas.
  • legend – Booleano que indica si se muestra la leyenda.

Si queremos un gráfico de barras horizontales, podemos usar el barh()método que toma los mismos argumentos.

Por ejemplo, tracemos un gráfico de barras horizontal naranja y verde, con el título "Dishes", con una cuadrícula, de tamaño de 5 por 6 pulgadas, y una leyenda:

import pandas as pd
import matplotlib.pyplot as plt

menu = pd.read_csv('indian_food.csv')
name_and_time = menu[['name','cook_time','prep_time']].head()

name_and_time.plot.barh(x='name',color =['orange','green'], title = "Dishes", grid = True, figsize=(5,6), legend = True)
plt.show()

Trazar histogramas con pandas

Los histogramas son útiles para mostrar la distribución de datos. Mirando una receta, no tenemos idea de si el tiempo de cocción está cerca del tiempo medio de cocción, o si lleva mucho tiempo. Los medios pueden ayudarnos con esto, hasta cierto punto, pero pueden ser engañosos o propensos a grandes barras de error.

Para tener una idea de la distribución, que nos da mucha información sobre el tiempo de cocción, querremos trazar un diagrama de histograma.

Con Pandas, podemos llamar a la hist()función en un DataFrame para generar su histograma:

DataFrame.hist(column=None, by=None, grid=True, xlabelsize=None, xrot=None, ylabelsize=None, yrot=None, ax=None, sharex=False, sharey=False, fcigsize=None, layout=None, bins=10, backend=None, legend=False,**kwargs)

El binsparámetro indica el número de contenedores que se utilizarán.

Una gran parte del trabajo con cualquier conjunto de datos es la limpieza y el preprocesamiento de datos. En nuestro caso, algunos alimentos no tienen los tiempos de cocción y preparación adecuados en la lista (y en su lugar tienen un -1valor).

Filtremoslos fuera de nuestro menú, antes de visualizar el histograma. Este es el tipo más básico de preprocesamiento de datos. En algunos casos, es posible que desee cambiar los tipos de datos (cadenas con formato de moneda en flotantes, por ejemplo) o incluso construir nuevos puntos de datos basados ​​en alguna otra variable.

Filtremos los valores no válidos y tracemos un histograma con 50 contenedores en el eje X:

import pandas as pd
import matplotlib.pyplot as plt

menu = pd.read_csv('indian_food.csv')
menu = menu[menu.cook_time != -1] # Filtering
cook_time = menu['cook_time']

cook_time.plot.hist(bins = 50)

plt.legend()
plt.show()

Esto resulta en:

En el eje Y podemos ver la frecuencia de los platos, mientras que en el eje X podemos ver cuánto tardan en cocinarse.

Cuanto más alta sea la barra, mayor será la frecuencia. Según este histograma, la mayoría de los platos tardan entre 0..80minutos en cocinarse. El número más alto de ellos se encuentra en la barra realmente alta, sin embargo, no podemos saber qué número es exactamente porque la frecuencia de nuestros tics es baja (uno cada 100 minutos).

Por ahora, intentemos cambiar el número de bins para ver cómo afecta eso a nuestro histograma. Después de eso, podemos cambiar la frecuencia de los tics.

Enfatizando datos con tamaños de contenedores

Intentemos trazar este histograma con 10bins en su lugar:

import pandas as pd
import matplotlib.pyplot as plt

menu = pd.read_csv('indian_food.csv')
menu = menu[menu.cook_time != -1] # Filtering
cook_time = menu['cook_time']

cook_time.plot.hist(bins = 10)

plt.legend()
plt.show()

Ahora, tenemos 10 contenedores en todo el eje X. Tenga en cuenta que solo 3 contenedores tienen cierta frecuencia de datos, mientras que el resto está vacío.

Ahora, quizás aumentemos el número de bins:

import pandas as pd
import matplotlib.pyplot as plt

menu = pd.read_csv('indian_food.csv')
menu = menu[menu.cook_time != -1] # Filtering
cook_time = menu['cook_time']

cook_time.plot.hist(bins = 100)

plt.legend()
plt.show()

Ahora, los contenedores están colocados de manera incómoda y separados, y nuevamente hemos perdido algo de información debido a esto. Siempre querrá experimentar con los tamaños de los contenedores y ajustarlos hasta que los datos que desea explorar se muestren bien.

La configuración predeterminada (el número de ubicación predeterminado es 10) habría dado como resultado un número de ubicación impar en este caso.

Cambiar la frecuencia de tick para el histograma de Pandas

Dado que estamos usando Matplotlib como motor para mostrar estos gráficos, también podemos usar cualquier técnica de personalización de Matplotlib.

Dado que nuestros ticks del eje X son un poco poco frecuentes, crearemos una matriz de números enteros, en incrementos de 20 pasos, entre 0y cook_time.max(), que devuelve la entrada con el número más alto.

Además, dado que tendremos muchas garrapatas en nuestro gráfico, las rotaremos 45 grados para asegurarnos de que encajen bien:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# Clean data and extract what we're looking for
menu = pd.read_csv('indian_food.csv')
menu = menu[menu.cook_time != -1] # Filtering
cook_time = menu['cook_time']

# Construct histogram plot with 50 bins
cook_time.plot.hist(bins=50)

# Modify X-Axis ticks
plt.xticks(np.arange(0, cook_time.max(), 20))
plt.xticks(rotation = 45) 

plt.legend()
plt.show()

Esto resulta en:

Trazado de varios histogramas

Ahora agreguemos el tiempo de preparación a la mezcla. Para agregar este histograma, lo trazaremos como un histograma separado, ambos con una opacidad del 60%.

Compartirán tanto el eje Y como el eje X, por lo que se superpondrán. Sin configurarlos para que sean un poco transparentes, es posible que no veamos el histograma debajo del segundo que trazamos:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# Filtering and cleaning
menu = pd.read_csv('indian_food.csv')
menu = menu[(menu.cook_time!=-1) & (menu.prep_time!=-1)] 

# Extracting relevant data
cook_time = menu['cook_time']
prep_time = menu['prep_time']

# Alpha indicates the opacity from 0..1
prep_time.plot.hist(alpha = 0.6 , bins = 50) 
cook_time.plot.hist(alpha = 0.6, bins = 50)

plt.xticks(np.arange(0, cook_time.max(), 20))
plt.xticks(rotation = 45) 
plt.legend()
plt.show()

Esto resulta en:

Podemos concluir que la mayoría de los platos se pueden preparar en menos de una hora, o en aproximadamente una hora. Sin embargo, hay algunos que tardan un par de días en prepararse, con tiempos de preparación de 10 horas y tiempos de cocción prolongados.

Personalización de gráficos de histogramas

Para personalizar histogramas, podemos usar los mismos argumentos de palabras clave que usamos con el diagrama de barras.

Por ejemplo, hagamos un histograma verde y rojo, con un título, una cuadrícula, una leyenda, del tamaño de 7 x 7 pulgadas:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

menu = pd.read_csv('indian_food.csv')
menu = menu[(menu.cook_time!=-1) & (menu.prep_time!=-1)] #filltering

cook_time = menu['cook_time']
prep_time = menu['prep_time']

prep_time.plot.hist(alpha = 0.6 , color="green", title="Cooking time", grid = True, bins = 50)
cook_time.plot.hist(alpha = 0.6, color="red", figsize = (7,7), grid = True, bins = 50)

plt.xticks(np.arange(0, cook_time.max(), 20))
plt.xticks(rotation = 45) 

plt.legend()
plt.show()

Y aquí está nuestro histograma de color navideño:

Trazado de parcelas de área con pandas

Los gráficos de área son útiles cuando se mira la correlación de dos parámetros. Por ejemplo, a partir de los gráficos del histograma, sería válido inclinarse hacia la idea de que los alimentos que tardan más en prepararse, tardan menos en cocinar.

Para probar esto, trazaremos esta relación usando la area()función:

DataFrame.plot.area(x=None, y=None, **kwargs)

Usemos la media de los tiempos de cocción, agrupados por tiempos de preparación para simplificar este gráfico:

time = menu.groupby('prep_time').mean() 

Esto da como resultado un nuevo DataFrame:

prep_time
5           20.937500
10          40.918367
12          40.000000
15          36.909091
20          36.500000
...
495         40.000000
500        120.000000

Ahora, timetrazaremos un diagrama de área con el DataFrame resultante :

import pandas as pd
import matplotlib.pyplot as plt

menu = pd.read_csv('indian_food.csv')
menu = menu[(menu.cook_time!=-1) & (menu.prep_time!=-1)]

# Simplifying the graph
time = menu.groupby('prep_time').mean() 
time.plot.area()

plt.legend()
plt.show()

Aquí, nuestra noción de la correlación original entre el tiempo de preparación y el tiempo de cocción se ha hecho añicos. Aunque otros tipos de gráficos pueden llevarnos a algunas conclusiones, existe una especie de correlación que implica que con tiempos de preparación más altos, también tendremos tiempos de cocción más altos. Que es lo opuesto a lo que hipotetizamos.

Esta es una gran razón para no ceñirse solo a un tipo de gráfico, sino explorar su conjunto de datos con múltiples enfoques.

Trazado de parcelas de área apilada

Los gráficos de área tienen un conjunto de argumentos de palabras clave muy similar a los gráficos de barras y los histogramas. Una de las excepciones notables sería:

  • stacked – Valor booleano que indica si dos o más parcelas se apilarán o no

Tracemos los tiempos de cocción y preparación para que estén apilados, de color rosa y morado, con una cuadrícula, de 8 x 9 pulgadas de tamaño, con una leyenda:

import pandas as pd
import matplotlib.pyplot as plt

menu = pd.read_csv('indian_food.csv')
menu = menu[(menu.cook_time!=-1) & (menu.prep_time!=-1)]

menu.plot.area()

plt.legend()
plt.show()

Trazar gráficos circulares con pandas

Los caracteres circulares son útiles cuando tenemos una pequeña cantidad de valores categóricos que necesitamos comparar. Son muy claros y van al grano, sin embargo, tenga cuidado. La legibilidad de los gráficos circulares disminuye con el menor aumento en el número de valores categóricos.

Para trazar gráficos circulares, usaremos la pie()función que tiene la siguiente sintaxis:

DataFrame.plot.pie(**kwargs)

Trazando los perfiles de sabor:

import pandas as pd
import matplotlib.pyplot as plt

menu = pd.read_csv('indian_food.csv')

flavors = menu[menu.flavor_profile != '-1']
flavors['flavor_profile'].value_counts().plot.pie()

plt.legend()
plt.show()

Esto resulta en:

De lejos, la mayoría de los platos son picantes y dulces.

Personalización de gráficos circulares

Para hacer que nuestro gráfico circular sea más atractivo, podemos modificarlo con los mismos argumentos de palabras clave que usamos en todas las alternativas de gráficos anteriores, con algunas novedades como:

  • shadow – Booleano que indica si los sectores del gráfico circular tienen una sombra
  • startangle – Ángulo inicial del gráfico circular

Para mostrar cómo funciona esto, tracemos las regiones de donde se originan los platos. Usaremos head()para tomar solo el primero 10, para no tener demasiados cortes.

Hagamos el pastel de color rosa, con el título “Estados”, déle una sombra y una leyenda y haga que comience en el ángulo de 15:

import pandas as pd
import matplotlib.pyplot as plt

menu = pd.read_csv('indian_food.csv')
states = (menu[menu.state != '-1'])['state'].value_counts().head(10)

# Colors to circle through
colors = ['lightpink','pink','fuchsia','mistyrose','hotpink','deeppink','magenta']

states.plot.pie(colors = colors, shadow = True, startangle = 15, title = "States")

plt.show()

Trazado de gráficos de densidad con pandas

Si tiene alguna experiencia con las estadísticas, probablemente haya visto un gráfico de densidad. Los gráficos de densidad son una representación visual de la densidad de probabilidad en un rango de valores.

Un histograma es un gráfico de densidad, que agrupa puntos de datos en categorías. El segundo gráfico de densidad más popular es el gráfico KDE (Estimación de densidad del núcleo); en términos simples, es como un histograma muy suave con un número infinito de bins.

Para trazar uno, usaremos la kde()función:

DataFrame.plot.kde(bw_method=None, ind=None, **kwargs)

Por ejemplo, trazaremos el tiempo de cocción:

import pandas as pd
import matplotlib.pyplot as plt
import scipy

menu = pd.read_csv('indian_food.csv')

time = (menu[menu.cook_time != -1])['cook_time']
time.value_counts().plot.kde()
plt.show()

Esta distribución se ve así:

En la sección Histograma, hemos tenido problemas para capturar toda la información y los datos relevantes usando contenedores, porque cada vez que generalizamos y agrupamos los datos, perdemos algo de precisión.

Con los gráficos de KDE, tenemos la ventaja de usar un número infinito de bins de manera efectiva. No se truncan ni se pierden datos de esta manera.

Trazar una matriz de dispersión (parcela) en pandas

Una forma un poco más compleja de interpretar los datos es utilizar matrices de dispersión. Que son una forma de tener en cuenta la relación de cada par de parámetros. Si ha trabajado con otras bibliotecas, este tipo de diagrama puede resultarle familiar como diagrama de pares.

Para trazar la matriz de dispersión, necesitaremos importar la scatter_matrix()función desde el pandas.plottingmódulo.

La sintaxis de la scatter_matrix()función es:

pandas.plotting.scatter_matrix(frame, alpha=0.5, figsize=None, ax=None, grid=False, diagonal="hist", marker=".", density_kwds=None, hist_kwds=None, range_padding=0.05, **kwargs)

Dado que estamos trazando relaciones de pares para múltiples clases, en una cuadrícula, todas las líneas diagonales en la cuadrícula serán obsoletas ya que compara la entrada consigo misma. Dado que este sería un espacio muerto, las diagonales se reemplazan con una gráfica de distribución univariante para esa clase.

El diagonalparámetro puede ser 'kde'o 'hist‘para gráficos de estimación de densidad de kernel o histograma.

Hagamos un diagrama de matriz de dispersión:

import pandas as pd 
import matplotlib.pyplot as plt
import scipy
from pandas.plotting import scatter_matrix

menu = pd.read_csv('indian_food.csv')

scatter_matrix(menu,diagonal="kde")

plt.show()

La trama debería verse así:

Trazar un diagrama de Bootstrap en Pandas

Pandas también ofrece un diagrama de Bootstrap para sus necesidades de trazado. Un gráfico de Bootstrap es un gráfico que calcula algunas estadísticas diferentes con diferentes tamaños de submuestra. Luego, con los datos acumulados sobre las estadísticas, genera la distribución de las propias estadísticas.

Usarlo es tan simple como importar el bootstrap_plot()método desde el pandas.plottingmódulo. La bootstrap_plot()sintaxis es:

pandas.plotting.bootstrap_plot(series, fig=None, size=50, samples=500, **kwds)

Y finalmente, tracemos un diagrama de Bootstrap:

import pandas as pd
import matplotlib.pyplot as plt
import scipy
from pandas.plotting import bootstrap_plot

menu = pd.read_csv('indian_food.csv')

bootstrap_plot(menu['cook_time'])
plt.show()

La trama de arranque se verá así:

Conclusión

En esta guía, hemos repasado la introducción a la visualización de datos en Python con Pandas. Hemos cubierto gráficos básicos como gráficos circulares, gráficos de barras, progresamos a gráficos de densidad como histogramas y gráficos de KDE.

Finalmente, hemos cubierto las matrices de dispersión y los gráficos de Bootstrap.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con tus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad