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

    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.

     

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *