本文目录导读:

我来详细讲解如何使用Pandas进行数据索引堆叠操作,包括常用的stack()、unstack()方法和相关案例。
基础堆叠操作
准备示例数据
import pandas as pd
import numpy as np
# 创建示例DataFrame
df = pd.DataFrame({
'A': ['A0', 'A1', 'A2'],
'B': ['B0', 'B1', 'B2'],
'C': ['C0', 'C1', 'C2']
}, index=['X', 'Y', 'Z'])
print("原始DataFrame:")
print(df)
stack() - 将列堆叠为行
# 将列索引堆叠为行索引
stacked_df = df.stack()
print("\n堆叠后的结果:")
print(stacked_df)
print("\n数据类型:", type(stacked_df))
# 重置索引
reset_df = df.stack().reset_index()
print("\n重置索引后:")
print(reset_df)
多层索引堆叠
创建多层索引数据
# 创建多层列索引
col_index = pd.MultiIndex.from_tuples([('A', 'x'), ('A', 'y'), ('B', 'x'), ('B', 'y')])
df_multi = pd.DataFrame(np.random.randn(3, 4),
index=['row1', 'row2', 'row3'],
columns=col_index)
print("多层列索引DataFrame:")
print(df_multi)
print("\n列索引:", df_multi.columns)
unstack() - 将行索引堆叠为列
# 创建多层行索引数据
array = [['A', 'A', 'B', 'B'], ['one', 'two', 'one', 'two']]
tuples = list(zip(*array))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
df_multi_row = pd.DataFrame(np.random.randn(4, 2),
index=index,
columns=['C1', 'C2'])
print("多层行索引DataFrame:")
print(df_multi_row)
# unstack操作 - 将最内层行索引转换为列
unstacked = df_multi_row.unstack()
print("\nunstack后的结果:")
print(unstacked)
# 指定层级unstack
unstacked_level = df_multi_row.unstack(level='first')
print("\n按'first'层级unstack:")
print(unstacked_level)
实际应用案例
案例1:销售数据透视
# 创建销售数据
sales_data = {
'Date': ['2024-01', '2024-01', '2024-02', '2024-02', '2024-03', '2024-03'],
'Product': ['A', 'B', 'A', 'B', 'A', 'B'],
'Region': ['North', 'South', 'North', 'South', 'North', 'South'],
'Sales': [100, 150, 120, 180, 130, 160]
}
df_sales = pd.DataFrame(sales_data)
print("原始销售数据:")
print(df_sales)
# 使用set_index创建多层索引
multi_sales = df_sales.set_index(['Date', 'Product'])
print("\n多层索引数据:")
print(multi_sales)
# 使用unstack将Product转换为列
pivot_sales = multi_sales.unstack()
print("\n透视后的数据:")
print(pivot_sales)
案例2:学生成绩分析
# 创建学生成绩数据
student_data = {
'Student': ['Alice', 'Alice', 'Bob', 'Bob', 'Charlie', 'Charlie'],
'Subject': ['Math', 'English', 'Math', 'English', 'Math', 'English'],
'Score': [95, 88, 78, 92, 85, 90],
'Grade': ['A', 'B', 'C', 'A', 'B', 'A']
}
df_students = pd.DataFrame(student_data)
print("学生成绩数据:")
print(df_students)
# 堆叠处理 - 将Subject转为列
stacked_students = df_students.set_index(['Student', 'Subject']).unstack()
print("\n堆叠后的成绩表:")
print(stacked_students)
# 重新堆叠回原始格式
re_stacked = stacked_students.stack()
print("\n重新堆叠回去:")
print(re_stacked)
案例3:时间序列数据堆叠
# 创建时间序列数据
dates = pd.date_range('2024-01-01', periods=4, freq='D')
df_time = pd.DataFrame({
'Temperature': [20, 22, 19, 24],
'Humidity': [65, 70, 75, 68],
'Pressure': [1013, 1015, 1012, 1014]
}, index=dates)
print("时间序列数据:")
print(df_time)
# 将列堆叠为行
stacked_time = df_time.stack()
print("\n堆叠后的时间序列:")
print(stacked_time)
# 恢复原始格式
unstacked_time = stacked_time.unstack()
print("\n恢复后的数据:")
print(unstacked_time)
高级堆叠技巧
复杂多层索引操作
# 创建三层索引数据
arrays = [['A', 'A', 'A', 'B', 'B', 'B'],
['one', 'one', 'two', 'one', 'one', 'two'],
['x', 'y', 'x', 'y', 'x', 'y']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second', 'third'])
df_complex = pd.DataFrame(np.random.randn(6, 2),
index=index,
columns=['C1', 'C2'])
print("三层索引DataFrame:")
print(df_complex)
# 指定层级堆叠
st = df_complex.unstack(level='second')
print("\n按'second'层级unstack:")
print(st)
# 多层堆叠
st_multi = df_complex.unstack(level=['second', 'third'])
print("\n按多层级unstack:")
print(st_multi)
处理缺失值
# 创建包含缺失值的数据
df_na = pd.DataFrame({
'A': [1, 2, np.nan],
'B': [4, np.nan, 6],
'C': [7, 8, 9]
}, index=['X', 'Y', 'Z'])
print("包含缺失值的DataFrame:")
print(df_na)
# 堆叠后处理缺失值
stacked_na = df_na.stack(dropna=False) # 保留NaN
print("\n保留NaN的堆叠:")
print(stacked_na)
stacked_na_drop = df_na.stack(dropna=True) # 删除NaN
print("\n删除NaN的堆叠:")
print(stacked_na_drop)
实用技巧总结
# 常用操作速查表
def stack_demo():
"""
堆叠操作示例函数
"""
# 1. 基本堆叠
df = pd.DataFrame(np.random.randn(3, 3),
columns=['A', 'B', 'C'])
print("1. 基本堆叠:")
print(df.stack())
print()
# 2. 指定层级堆叠
columns = pd.MultiIndex.from_product([['A', 'B'], ['x', 'y']])
df_multi = pd.DataFrame(np.random.randn(3, 4), columns=columns)
print("2. 多层堆叠:")
print(df_multi.stack(level=0))
print()
# 3. 使用fillna处理缺失
print("3. 处理缺失值:")
print(df_multi.stack(dropna=False))
# 执行演示
stack_demo()
核心要点
- stack(): 将列索引转换为行索引(表格变长)
- unstack(): 将行索引转换为列索引(表格变宽)
- level参数: 指定要操作的索引层级
- dropna参数: 控制是否删除缺失值
- 堆叠操作常用于数据透视和格式转换
这些技巧在数据清洗和重组中非常有用,特别是处理多维数据时,记住合理利用level参数来处理多层索引的特定层级。