La mayoría de las personas han utilizado tablas dinámicas en Excel en algún momento. Pandas también proporciona una función similar llamada pivot_table. Aunque pivot_table es muy útil, a menudo es necesario recordar su sintaxis para formatear la salida deseada. Por lo tanto, este artículo se centrará en explicar la función pivot_table de pandas y enseñar cómo utilizarla para el análisis de datos.
Si no está familiarizado con este concepto, Wikipedia ofrece una explicación detallada. Por cierto, ¿sabía que Microsoft registró la marca PivotTable? La tabla dinámica que discutimos aquí no es la PivotTable de Microsoft.
Como beneficio adicional, he creado una hoja de referencia simple para resumir el uso de pivot_table. La encontrará al final de este artículo y espero que le sea de ayuda.
Datos
Un desafío al usar pivot_table en pandas es asegurarse de comprender sus datos y saber claram qué problema se pretende resolver con la tabla dinámica. Aunque pivot_table parece una función simple, puede realizar un análisis de datos potente rápidamente.
En este artículo, rastreamos un canal de ventas (también conocido como embudo). El problema básico es que algunos ciclos de ventas son largos (piense en "software empresarial", "equipos de capital", etc.), y los gerentes quieren obtener más detalles sobre todo el año.
Las preguntas típicas incluyen:
- ¿Cuál es los ingresos de este canal?
- ¿Cuáles son los productos del canal?
- ¿Quién tiene qué producto en qué etapa?
- ¿Cuál es la probabilidad de que finalicemos el trato antes de fin de año?
Muchas empresas utilizarán herramientas CRM u otro software de ventas para rastrear este proceso. Aunque pueden tener herramientas efectivas para analizar los datos, definitivamente alguien necesitará exportar los datos a Excel y usar una herramienta de tabla dinámica para resumirlos.
Usar una tabla dinámica de Pandas es una buena opción porque tiene las sigiuentes ventajas:
- Más rápido (una vez configurado)
- Autoexplicativo (al ver el código, sabrá lo que hace)
- Fácil de generar informes o correos electrónicos
- Más flexible, ya que puede definir funciones de agregación personalizadas
Cargar los datos
Primero, establezcamos el entorno necesario.
import pandas as pd
import numpy as np
Recordatorio de versión
La API de pivot_table ha cambiado con el tiempo, por lo que para que los ejemplos de código de este artículo funcionen correctamente, asegúrese de tener instalada una versión reciente de Pandas (>0.15). Los ejemplos de este artículo también utilizan el tipo de dato category, lo que también requiere una versión reciente.
Primero, carguemos los datos de nuestro canal de ventas en un DataFrame.
datos_ventas = pd.read_excel("datos_ventas.xlsx")
datos_ventas.head()
Para mayor comodidad, definiremos la columna "Estado" como category y estableceremos el orden en que queremos verla.
datos_ventas["Estado"] = datos_ventas["Estado"].astype("category")
datos_ventas["Estado"].cat.set_categories(["ganado", "pendiente", "presentado", "rechazado"], inplace=True)
Procesamiento de datos
Como vamos a crear una tabla dinámica, creo que el método más fácil es hacerlo paso a paso. Agregue elementos y verifique cada paso para verificar que está obteniendo los resultados deseados. No tema experimentar con el orden y las variables para encontrar la vista que mejor satisfaga sus necesidades.
La tabla dinámica más simple debe tener un DataFrame y un índice. En este caso, usaremos la columna "Nombre" como nuestro índice.
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Nombre"])
También puede tener múltiples índices. De hecho, la mayoría de los parámetros de pivot_table pueden obtener múltiples valores a través de una lista.
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Nombre", "Representante", "Gerente"])
Esto es interesante pero no especialmente útil. Lo que probablemente queramos hacer es ver los resultados estableciendo "Gerente" y "Representante" como índices. Para lograr esto, simplemente cambiamos el índice.
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Representante"])
Como puede ver, la tabla dinámica es inteligente, ya ha comenzado a agrupar las columnas "Representante" y "Gerente" para realizar la agregación y resumen de datos. Ahora exploremos qué puede hacer la tabla dinámica por nosotros.
Para ello, las columnas "Cuenta" y "Cantidad" no son particularmente útiles para nosotros. Por lo tanto, podemos eliminar esas columnas que no nos interesan definiendo explícitamente las columnas que nos importan usando el parámetro "values".
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Representante"], values=["Precio"])
La columna "Precio" calcula automáticamente el promedio de los datos, pero también podemos contar o sumar los elementos de esta columna. Para agregar estas funcionalidades, es fácil usar aggfunc y np.sum.
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Representante"], values=["Precio"], aggfunc=np.sum)
aggfunc puede contener muchas funciones. Intentemos un método que use las funciones mean y len de numpy para contar.
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Representante"], values=["Precio"], aggfunc=[np.mean, len])
Si queremos analizar las ventas por diferentes productos, el parámetro "columns" nos permitirá definir una o más columnas.
Columnas vs. Valores
Un lugar confuso en pivot_table es el uso de "columns" (columnas) y "values" (valores). Recuerde que el parámetro "columns" es opcional y proporciona un método adicional para dividir los valores reales que le interesan. Sin embargo, la función de agregación aggfunc finalmente se aplica a los elementos que enumera en el parámetro "values".
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Representante"], values=["Precio"],
columns=["Producto"], aggfunc=[np.sum])
Sin embargo, los valores no numéricos (NaN) son un poco distractores. Si queremos eliminarlos, podemos usar "fill_value" para establecerlos en 0.
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Representante"], values=["Precio"],
columns=["Producto"], aggfunc=[np.sum], fill_value=0)
De hecho, creo que agregar la columna "Cantidad" nos será útil, así que agreguemos "Cantidad" a la lista de "values".
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Representante"], values=["Precio", "Cantidad"],
columns=["Producto"], aggfunc=[np.sum], fill_value=0)
Interesantemente, puede establecer varios elementos como índice para obtener diferentes representaciones visuales. En el siguiente código, eliminamos "Producto" de "columns" y lo agregamos a la variable "index".
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Representante", "Producto"],
values=["Precio", "Cantidad"], aggfunc=[np.sum], fill_value=0)
Para este conjunto de datos, este método de visualización parece tener más sentido. Sin embargo, ¿qué si queremos ver algunos datos totales? margins=True puede lograr esto por nosotros.
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Representante", "Producto"],
values=["Precio", "Cantidad"],
aggfunc=[np.sum, np.mean], fill_value=0, margins=True)
A continuación, analicemos este canal desde una perspectiva de gestión más alta. Según nuestra definición anterior de category, observe cómo ahora se ordena "Estado".
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Estado"], values=["Precio"],
aggfunc=[np.sum], fill_value=0, margins=True)
Una característica muy conveniente es que puede pasar un diccionario a aggfunc para ejecutar diferentes funciones en los valores que elija. Sin embargo, esto tiene un efecto secundario: las etiquetas deben ser más concisas.
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Estado"], columns=["Producto"], values=["Cantidad", "Precio"],
aggfunc={"Cantidad": len, "Precio": np.sum}, fill_value=0)
Además, también puede proporcionar una serie de funciones de agregación y aplicarlas a cada elemento en "values".
tabla_dinamica = pd.pivot_table(datos_ventas, index=["Gerente", "Estado"], columns=["Producto"], values=["Cantidad", "Precio"],
aggfunc={"Cantidad": len, "Precio": [np.sum, np.mean]}, fill_value=0)
Tal vez, poner todas estas cosas juntas a la vez pueda ser un poco abrumador, pero una vez que comience a procesar estos datos y agregue nuevos elementos paso a paso, podrá apreciar cómo funciona. Mi regla general general es que una vez que usa múltiples "grouby", debe evaluar si usar una tabla dinámica es una buena opción.
Filtrado avanzado de tablas dinámicas
Una vez que genera los datos necesarios, estos existen en un DataFrame. Por lo tanto, puede usar las funciones estándar de DataFrame para filtrarlos.
Si solo desea ver los datos de un gerente (por ejemplo, Debra Henley), puede hacerlo así:
tabla_dinamica.query('Gerente == ["Debra Henley"]')
Podemos ver todas las transacciones pendientes y ganadas de la siguiente manera:
tabla_dinamica.query('Estado == ["pendiente", "ganado"]')
Esta es una característica muy potente de pivot_table, por lo que una vez que obtiene los datos en el formato de tabla dinámica que necesita, no olvide que ahora tiene el poder de pandas a su disposición.
Hoja de referencia
Para intentar resumir todo esto, he creado una hoja de referencia que espero le ayude a recordar cómo usar la pivot_table de pandas.