Pandas en Python, con ejemplos -Parte III- Pivot_table


El proyecto de este post lo puedes descargar pulsando AQUI.

Sobre la librería de Pandas vamos a hablar de los siguientes temas en las entradas:

  1. Parte I: Introducción a Pandas.
  2. Parte II: DataFrame: Lectura y Escritura, Mergeo de DataFrame's y GroupBy.
  3. Parte III: Operaciones de "Pivot_table" con DataFrame's.

Pivot_table

La funcionlidad "Pivot_table" es muy utilizada y popular en las conocidas "hojas de cálculo" tipo, OpenOffice, LibreOffice, Excel, Lotus, etc. Esta funcionalidad nos permite agrupar, ordenar, calcular datos y manejar datos de una forma muy similar a la que se hace con las hojas de cálculo.

Esta función de pandas admite los siguientes parámetros, que podéis consultar con más detalle pulsando AQUI:


DataFrame.pivot_table(values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True)


La principal función del "Pivot_table" son las agrupaciones de datos a las que se les suelen aplicar funciones matemáticas como sumatorios, promedios, etc. Si no indicamos en el parámetro 'aggfunc' que opereción queremos hacer; por defecto, nos calculará la media de todas aquellas columnas que sean de tipo numérico.

Pasemos a ver un primer ejemplo, en el que vamos a utilizar el dataset de MovieLens con 100K votos. Para ello leeremos los datos de los ficheros en los que tenemos la información de los usuarios, las películas y los votos al igual que hicimos en la entrada "DataFrame: Lectura y Escritura, Mergeo de DataFrame's y GroupBy":


import pandas as pd
import numpy as np

# Load Data
userHeader = ['user_id', 'gender', 'age', 'ocupation', 'zip']
users = pd.read_table('dataSet/users.txt', engine='python', sep='::', header=None, names=userHeader)

movieHeader = ['movie_id', 'title', 'genders']
movies = pd.read_table('dataSet/movies.txt', engine='python', sep='::', header=None, names=movieHeader)

ratingHeader = ['user_id', 'movie_id', 'rating', 'timestamp']
ratings = pd.read_table('dataSet/ratings.txt', engine='python', sep='::', header=None, names=ratingHeader)

# Merge data
mergeRatings = pd.merge(pd.merge(users, ratings), movies)


ADVERTENCIA!! para la copia o "clone" de DataFrame's:

A continuación comparto un método ('cloneDF(df)') devuelve una copia del DataFrame que se pasa como parámetro:


# Clone DataFrame
def cloneDF(df):
    return pd.DataFrame(df.values.copy(), df.index.copy(), df.columns.copy()).convert_objects(convert_numeric=True)


El primer ejemplo que vamos a ver, va a ser el de poner como índices las columnas de 'movie_id' y 'title'. De esta forma, nos hará una agrupación por título e identificador de la película. Esto lo hacemos de la siguiente manera:


# Simple pivot (Groupby + avg)
df_1 = cloneDF(mergeRatings)
df_1 = df_1.pivot_table(index=['movie_id', 'title'])
print 'Columns(movie_id + title) to Index: \n%s' % df_1[:5]


Como resultado, vamos a obtener los 5 primeros elementos de esta agrupación del DataFrame y al no indicarle el parámetro  'aggfunc' nos calculará la media de todos los valores numéricos:

                                                   age  ocupation    rating  ....
movie_id title                                                                
1        Toy Story (1995)                    27.700530   8.067886  4.146846  .... 
2        Jumanji (1995)                      27.800285   7.680456  3.201141  .... 
3        Grumpier Old Men (1995)             29.276151   7.826360  3.016736  ....
4        Waiting to Exhale (1995)            27.788235   6.752941  2.729412  ....
5        Father of the Bride Part II (1995)  27.425676   7.506757  3.006757  ....

Podemos hacer esta misma operación indicandole con el parámetros 'values' sobre que columnas queremos que nos calcule la media; ya que como vemos no tiene mucho sentido que nos calcule la media de la columna "ocupation" que es un identificador de la profesión de cada usuario. Pasamos a indicarle (con "values=[‘rating’, ‘age’]") que solo nos calcule el valor medio de la agrupación de las columnas 'rating' y 'age':


df_2 = cloneDF(mergeRatings)
df_2 = df_2.pivot_table(index=['movie_id', 'title'], values=['rating', 'age'])
print 'Columns(movie_id + title) to Index and avg by values \n%s' % df_2[:5]


Como resultado tenemos lo siguiente:

Columns(movie_id + title) to Index and avg by values 
                                                   age    rating
movie_id title                                                  
1        Toy Story (1995)                    27.700530  4.146846
2        Jumanji (1995)                      27.800285  3.201141
3        Grumpier Old Men (1995)             29.276151  3.016736
4        Waiting to Exhale (1995)            27.788235  2.729412
5        Father of the Bride Part II (1995)  27.425676  3.006757

El siguiente paso que vamos a dar, es el de indicarle que operaciones queremos hacer y sobre que columna. En este caso vamos ha "pivotar" sobre el título de la película y su identificador, y vamos a aplicar sobre la columna 'rating' las operaciones de sumatorio, conteo y media. Para hacer estos cálculo haremos uso de la librería 'numpy':


df_3 = cloneDF(mergeRatings)
df_3 = df_3.pivot_table(index=['movie_id', 'title'], values=['rating'], aggfunc=[np.sum, np.size, np.mean])
print 'Columns(movie_id + title) to Index and specific functions by values \n%s' % df_3[:5]


Como resultado tenemos lo siguiente:

Columns(movie_id + title) to Index and specific functions by values 
                                               sum   size      mean
                                            rating rating    rating
movie_id title                                                     
1        Toy Story (1995)                     8613   2077  4.146846
2        Jumanji (1995)                       2244    701  3.201141
3        Grumpier Old Men (1995)              1442    478  3.016736
4        Waiting to Exhale (1995)              464    170  2.729412
5        Father of the Bride Part II (1995)    890    296  3.006757

Como último ejemplo vamos a seguir agrupando por título e identificador de película y aplicaremos sobre la columna 'rating' la función que nos calcule la media de sus valores pasándole el parámetro 'aggfunc', pero en este caso vamos a indicarle con el parámetro 'columns' que nos muestre en columnas separadas todos los valores distintos que tiene en este caso la columna 'gender' (columns=[‘gender’]) y además con el parámetro 'margins=True' le indicaremos que añada una nueva columna con los cálculos de todos lo valores. En resumen, tendremos como resultado una agrupación por película e identificador en el que veremos el votos medio que realizan los hombres y las mujeres por separado y (con el parámetro 'margins=True') el voto de la película. Esto lo hacemos de la siguiente manera:


df_4 = cloneDF(mergeRatings)
df_4 = df_4.pivot_table(index=['movie_id', 'title'], values=['rating'], columns=['gender'], aggfunc=[np.mean],
                        fill_value=-1, margins=True)
print 'Columns(movie_id + title) to Index and avg rating applied by gender \n%s' % df_4[:5]


Como resultado tenemos lo siguiente:


Columns(movie_id + title) to Index and avg rating applied by gender 
                                                 mean                    
                                               rating                    
gender                                              F         M       All
movie_id title                                                           
1        Toy Story (1995)                    4.187817  4.130552  4.146846
2        Jumanji (1995)                      3.278409  3.175238  3.201141
3        Grumpier Old Men (1995)             3.073529  2.994152  3.016736
4        Waiting to Exhale (1995)            2.976471  2.482353  2.729412
5        Father of the Bride Part II (1995)  3.212963  2.888298  3.006757

Podemos observar como de diferentes votan los hombres y las mujeres; por ejemplo, la película "Waiting to Exhale" parece que les gusta algo más a los hombres que a las mujeres ya que les separa casi 0.5 puntos de media.

CONCLUSIONES:

La librería de Pandas es una librería destinada al análisis de datos muy utilizada por los 'data scientists' y como se ha podido obversar en este tutorial, hemos podido analizar datos relacionados con los votos emitidos por personas sobre películas y gracias a las operaciones de "Pivot_table" hemos sacado algunos datos que pueden ser relevantes. Dado que es un tutorial de introducción se han visto pocas cosas operaciones con "Pivot_table", pero si que se han visto las necesarias como para empezar a trabajar con esta funcionalidad y una vez que se tenga soltura, seguro que podréis hacer un análisis de datos muy exhaustivo y preciso ya que es una librería que utilizan hoy en dia los data scientists profesionales.

Comparte esta entrada en:
Safe Creative #1401310112503
Pandas en Python, con ejemplos -Parte III- Pivot_table por "www.jarroba.com" esta bajo una licencia Creative Commons
Reconocimiento-NoComercial-CompartirIgual 3.0 Unported License.
Creado a partir de la obra en www.jarroba.com

Deja una respuesta

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

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.