Función Pandas df.unstack()
df.unstack()Es un método miembro de DataFrame, utilizado paraconvertir los índices de filas en índices de columnas. Expande los datos con índice jerárquico, moviendo uno o más niveles del índice de filas a las columnas.
Esta es una operación importante de remodelación de datos, generalmente se usa junto constack()para lograr la conversión mutua de datos.
Definición de la palabra: unstackSignifica "desarmar, expandir"; aquí se refiere a "expandir" el índice de filas en columnas, convirtiendo una tabla larga en una tabla ancha.
Sintaxis básica y parámetros
df.unstack()Es un método de instancia de DataFrame, se invoca mediante el operador punto.
Formato de sintaxis
DataFrame.unstack(level=-1, fill_value=None)
Descripción de parámetros
- Parámetro:
level- Tipo: int, str, lista de int o lista de str.
- Descripción: especifica el nivel que se va a expandir a columnas. Para índices multinivel, se puede especificar el número de nivel (comenzando desde 0) o el nombre del nivel. El valor predeterminado es -1, que indica el nivel más interno.
- Parámetro:
fill_value- Tipo: escalar o None.
- Descripción: valor utilizado para rellenar los valores faltantes generados por la operación unstack. El valor predeterminado es None, conserva NaN.
Descripción de la función
- Valor de retorno: devuelve un Series o DataFrame. Si el DataFrame original solo tiene un nivel de fila expandido, devuelve Series; de lo contrario, devuelve DataFrame.
- Efecto: mueve uno o más niveles del índice de filas al índice de columnas, produciendo un formato de datos más ancho. Los datos expandidos están en "formato ancho", lo que facilita la visualización y comparación.
Ejemplos
A través de una serie de ejemplos de simples a complejos, dominaremos completamentedf.unstack()el uso de.
Ejemplo 1: Uso básico - convertir filas en columnas
Ejemplo
# 1. Crear datos en formato largo
df = pd.DataFrame({
'product': ['A', 'A', 'B', 'B', 'C', 'C'],
'region': ['North', 'South', 'North', 'South', 'North', 'South'],
'sales': [100, 150, 200, 180, 220, 250]
})
print("=== Datos originales en formato largo ===")
print(df)
# 2. Establecer índice jerárquico
df_indexed = df.set_index(['product', 'region'])
print("n=== Después de establecer el índice jerárquico ===")
print(df_indexed)
# 3. Usar df.unstack() para convertir el índice interno en columnas
unstacked = df_indexed.unstack()
print("n=== Resultado de df.unstack() ===")
print(unstacked)
# 4. Vista simplificada
print("n=== Solo ver las ventas ===")
print(unstacked['sales'])
Resultado esperado de la ejecución:
=== 原始长格式数据 ===
product region sales
0 A North 100
1 A South 150
2 B North 200
3 B South 180
4 C North 220
5 C South 250
n=== 设置层次化索引后 ===
sales
product region
A North 100
South 150
B North 200
South 180
C North 220
South 250
n=== df.unstack() 结果 ===
sales
region North South
product
A 100 150
B 200 180
C 220 250
n=== 只看销售额 ===
region North South
product
A 100 150
B 200 180
C 220 250
Análisis del código:
- Los datos originales están en formato largo; cada fila registra las ventas de un producto en una región.
- Usando
set_index()Se crea un índice jerárquico (product como nivel externo, region como nivel interno). unstack()Se mueve el índice interno region a la posición de las columnas.- El resultado está en formato ancho, lo que permite comparar visualmente los datos de ventas de diferentes productos en diferentes regiones.
Ejemplo 2: Expansión de índices multinivel
Cuando el DataFrame tiene un índice de filas multinivel, se puede especificar el nivel que se desea expandir.
Ejemplo
# 1. Crear datos con índice de filas multinivel
df = pd.DataFrame({
'year': [2023, 2023, 2023, 2023, 2024, 2024, 2024, 2024],
'quarter': ['Q1', 'Q1', 'Q2', 'Q2', 'Q1', 'Q1', 'Q2', 'Q2'],
'product': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
'sales': [100, 150, 200, 180, 220, 250, 230, 270]
})
print("=== Datos originales ===")
print(df)
# 2. Establecer índice multinivel
df_indexed = df.set_index(['year', 'quarter', 'product'])
print("n=== Establecer índice multinivel ===")
print(df_indexed)
# 3. Expandir el nivel más interno (product, nivel=-1 por defecto)
print("n=== Expandir el nivel product (por defecto) ===")
unstacked_inner = df_indexed.unstack()
print(unstacked_inner['sales'])
# 4. Expandir el nivel intermedio (quarter)
print("n=== Expandir el nivel quarter ===")
unstacked_quarter = df_indexed.unstack(level='quarter')
print(unstacked_quarter['sales'])
# 5. Expandir el nivel externo (year)
print("n=== Expandir el nivel year ===")
unstacked_year = df_indexed.unstack(level='year')
print(unstacked_year['sales'])
# 6. Expandir múltiples niveles a la vez
print("n=== Expandir year y product a la vez ===")
unstacked_multi = df_indexed.unstack(level=['year', 'product'])
print(unstacked_multi['sales'])
Resultado esperado de la ejecución:
=== 原始数据 ===
year quarter product sales
0 2023 Q1 A 100
1 2023 Q1 B 150
2 2023 Q2 A 200
3 2023 Q2 B 180
4 2024 Q1 A 220
5 2024 Q1 B 250
6 2024 Q2 A 230
7 2024 Q2 B 270
n=== 设置多层索引 ===
sales
year quarter product
2023 Q1 A 100
B 150
Q2 A 200
B 180
2024 Q1 A 220
B 250
Q2 A 230
B 270
n=== 展开 product 层(默认)===
product A B
year quarter
2023 Q1 100 150
Q2 200 180
2024 Q1 220 250
Q2 230 270
n=== 展开 quarter 层 ===
quarter Q1 Q2
year product
2023 A 100 200
B 150 180
2024 A 220 230
B 250 270
n=== 展开 year 层 ===
year 2023 2024
quarter product
Q1 A 100 220
B 150 250
Q2 A 200 230
B 180 270
n=== 同时展开 year 和 product ===
year 2023 2024
product A B A B
quarter
Q1 100 150 220 250
Q2 200 180 230 270
Análisis del código:
- Para un DataFrame con índice multinivel, se puede usar
levelel parámetro para especificar qué nivel expandir. - Por defecto
level=-1se expande el nivel más interno (product). - Expandir diferentes niveles produce diferentes disposiciones de datos, lo que facilita analizar los datos desde diferentes perspectivas.
Ejemplo 3: Uso de fill_value para manejar valores faltantes
Usandofill_valueel parámetro se pueden rellenar los valores faltantes generados después de unstack.
Ejemplo
import numpy as np
# 1. Crear datos incompletos (no todas las combinaciones producto-región tienen datos)
df = pd.DataFrame({
'product': ['A', 'A', 'B', 'C'],
'region': ['North', 'South', 'North', 'East'],
'sales': [100, 150, 200, 220]
})
print("=== Datos originales (incompletos) ===")
print(df)
# 2. Crear índice jerárquico y aplicar unstack
df_indexed = df.set_index(['product', 'region'])
print("n=== Índice jerárquico ===")
print(df_indexed)
# 3. No rellenar valores faltantes
print("n=== Sin rellenar valores faltantes ===")
unstacked = df_indexed.unstack()
print(unstacked)
print(f"Cantidad de valores faltantes: {unstacked['sales'].isna().sum().sum()}")
# 4. Usar fill_value=0 para rellenar valores faltantes
print("n=== fill_value=0 ===")
unstacked_fill = df_indexed.unstack(fill_value=0)
print(unstacked_fill)
print(f"Cantidad de valores faltantes: {unstacked_fill['sales'].isna().sum().sum()}")
Resultado esperado de la ejecución:
=== 原始数据(不完整)===
product region sales
0 A North 100
1 A South 150
2 B North 200
3 C East 220
n=== 层次化索引 ===
sales
product region
A North 100
South 150
B North 200
C East 220
n=== 不填充缺失值 ===
sales
region East North South
product
A NaN 100.0 150.0
B NaN 200.0 NaN
C 220.0 NaN NaN
缺失值数量: 5
n=== fill_value=0 ===
sales
region East North South
product
A 0 100 150
B 0 200 0
C 220 0 0
缺失值数量: 0
Análisis del código:
- Cuando los datos originales están incompletos, unstack genera valores faltantes (NaN).
- Usando
fill_valueel parámetro se puede especificar un valor de relleno para evitar errores en cálculos posteriores. - Normalmente se rellena con 0 para indicar "sin datos" o "la combinación no existe".
Ejemplo 4: Uso combinado de unstack y stack
unstack()ystack()Son operaciones inversas entre sí; usándolas juntas se puede remodelar datos de forma flexible.
Ejemplo
# 1. Crear datos iniciales en formato ancho
df = pd.DataFrame({
'product': ['A', 'B', 'C'],
'North': [100, 150, 200],
'South': [180, 170, 160],
'East': [190, 200, 210]
})
print("=== Datos originales en formato ancho ===")
print(df)
# 2. Primero aplicar stack para convertir a formato largo
print("n=== paso 1: stack para convertir a formato largo ===")
stacked = df.set_index('product').stack()
print(stacked)
# 3. Luego aplicar unstack para volver (verificar la reversibilidad)
print("n=== paso 2: unstack para volver a formato ancho ===")
restored = stacked.unstack()
print(restored)
# 4. Práctica: reorganizar datos
print("n=== Práctica: mover region a las columnas ===")
# Original: product como índice de filas, region como columnas
# Objetivo: region como índice de filas, product como columnas
result = df.set_index('product').unstack().unstack(level=-1)
print(result)
# 5. Usar reorder_levels para ajustar el orden de los niveles
print("n=== Usar reorder_levels para ajustar los niveles ===")
# Crear índice de dos niveles
df_multi = pd.DataFrame(
[[100, 200], [150, 180], [190, 210]],
index=pd.MultiIndex.from_tuples([
('A', 'North'), ('B', 'North'), ('C', 'North')
], names=['product', 'region']),
columns=['2023', '2024']
)
print("Datos originales:")
print(df_multi)
# Ajustar el orden de los niveles
print("nDespués del ajuste (año en el nivel externo):")
print(df_multi.unstack(level='region'))
Resultado esperado de la ejecución:
=== 原始宽格式数据 === product North South East 0 A 100 180 190 1 B 150 170 ...
Análisis del código:
stack()yunstack()Son un par de operaciones inversas.- Primero stack y luego unstack, en teoría se puede restaurar la forma original (ignorando las diferencias de valores de relleno).
- Se pueden lograr diferentes disposiciones de datos mediante diferentes combinaciones de nivel.
- En el análisis de datos real, a menudo es necesario ajustar repetidamente la forma de los datos para adaptarse a diferentes necesidades de análisis.
Otras extensionesConsejo:
unstack()ystack()Son herramientas fundamentales para la remodelación de datos.unstack()"Desarman" las filas en columnas (de largo a ancho),stack()"apilan" las columnas en filas (de ancho a largo).
Funciones comunes de Pandas