Saltar al contenido

Pandas en Python, con ejemplos -Parte III- Pivot_table

Aprende a usar pivot_table de Pandas para agrupar y calcular datos como en una hoja de cálculo, con el dataset MovieLens de 100K votos.

El proyecto de este post lo puedes descargar pulsando AQUI.

Pivot_table

La funcionalidad «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 operació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)


Cuidado

 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 qué operaciones queremos hacer y sobre qué columna. En este caso vamos a «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álculos 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 los valores. En resumen, tendremos como resultado una agrupación por película e identificador en el que veremos el voto 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 cómo 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 observar 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 operaciones con «Pivot_table», pero sí 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 día los data scientists profesionales.

«Pandas en Python, con ejemplos -Parte III- Pivot_table», de Ricardo Moya en jarroba.com, con licencia Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0. Obra registrada en Safe Creative.

Ricardo Moya

Me dedico profesionalmente al Machine Learning y al Big Data. Me gusta aprender tecnologías nuevas y explicarlas de la mejor manera posible en esta web.

Te puede interesar

Comentarios

Deja un comentario


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