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 un comentario

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

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies

ACEPTAR
Aviso de cookies