Pandas 数据变形与重塑全面指南
1. 引言
在数据分析过程中,我们经常需要将数据从一种结构转换为另一种结构,以适应不同的分析需求。Pandas 提供了丰富的数据变形与重塑功能,包括旋转(pivot)、堆叠(stack)、融合(melt)等多种操作。本文将详细介绍这些功能,并通过实际代码示例展示如何使用它们。
2. 透视表操作 (pivot 和 pivot_table)
2.1 pivot 基础操作
pivot
用于将长格式数据转换为宽格式。
import pandas as pd
import numpy as np# 创建示例数据
data = {'Date': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02'],'Variable': ['A', 'B', 'A', 'B'],'Value': [10, 20, 30, 40]
}
df = pd.DataFrame(data)# 使用pivot进行重塑
pivot_df = df.pivot(index='Date', columns='Variable', values='Value')
print("Pivot结果:\n", pivot_df)
输出:
Variable A B
Date
2023-01-01 10 20
2023-01-02 30 40
解释:
index
: 指定作为行索引的列columns
: 指定作为列名的列values
: 指定填充值的列
2.2 pivot_table 高级透视
pivot_table
支持聚合功能,适合处理重复值。
# 创建有重复值的数据
data = {'Date': ['2023-01-01', '2023-01-01', '2023-01-01', '2023-01-02'],'Variable': ['A', 'B', 'A', 'B'],'Value': [10, 20, 30, 40]
}
df = pd.DataFrame(data)# 使用pivot_table进行聚合
pivot_table_df = pd.pivot_table(df, values='Value', index='Date', columns='Variable', aggfunc=np.mean)
print("\nPivot Table结果:\n", pivot_table_df)
输出:
Value A B
Date
2023-01-01 20 20
2023-01-02 NaN 40
解释:
aggfunc
: 指定聚合函数,默认为np.mean
- 可以处理重复值,对相同索引和列的组合进行聚合
3. 堆叠与反堆叠 (stack 和 unstack)
3.1 stack 操作
stack
将列转换为行,产生多级索引。
# 创建宽格式数据
wide_df = pd.DataFrame({'A': [1, 2],'B': [3, 4],'C': [5, 6]
}, index=['X', 'Y'])# 使用stack进行堆叠
stacked = wide_df.stack()
print("\nStack结果:\n", stacked)
输出:
X A 1B 3C 5
Y A 2B 4C 6
dtype: int64
3.2 unstack 操作
unstack
是 stack
的逆操作,将行转换为列。
# 使用unstack进行反堆叠
unstacked = stacked.unstack()
print("\nUnstack结果:\n", unstacked)
输出:
A B C
X 1 3 5
Y 2 4 6
4. 融合与宽变长 (melt 和 wide_to_long)
4.1 melt 操作
melt
将宽格式数据转换为长格式。
# 创建宽格式数据
wide_df = pd.DataFrame({'ID': [1, 2],'Name': ['Alice', 'Bob'],'Math': [90, 85],'Physics': [80, 75]
})# 使用melt进行融合
melted = pd.melt(wide_df, id_vars=['ID', 'Name'], value_vars=['Math', 'Physics'],var_name='Subject', value_name='Score')
print("\nMelt结果:\n", melted)
输出:
ID Name Subject Score
0 1 Alice Math 90
1 2 Bob Math 85
2 1 Alice Physics 80
3 2 Bob Physics 75
4.2 wide_to_long 操作
wide_to_long
是更灵活的宽变长转换方法。
# 创建复杂宽格式数据
wide_df = pd.DataFrame({'ID': [1, 2],'Name': ['Alice', 'Bob'],'Score_Math_2022': [90, 85],'Score_Physics_2022': [80, 75],'Score_Math_2023': [95, 88],'Score_Physics_2023': [85, 78]
})# 使用wide_to_long进行转换
long_df = pd.wide_to_long(wide_df, stubnames=['Score'], i=['ID', 'Name'], j='Year', sep='_', suffix='\\w+')
print("\nWide to Long结果:\n", long_df)
5. 虚拟变量转换 (get_dummies 和 from_dummies)
5.1 get_dummies 操作
get_dummies
将分类变量转换为虚拟/指示变量。
# 创建分类数据
df = pd.DataFrame({'Color': ['Red', 'Blue', 'Green', 'Blue', 'Red']
})# 使用get_dummies进行转换
dummies = pd.get_dummies(df, columns=['Color'])
print("\nGet Dummies结果:\n", dummies)
输出:
Color_Blue Color_Green Color_Red
0 0 0 1
1 1 0 0
2 0 1 0
3 1 0 0
4 0 0 1
5.2 from_dummies 操作
from_dummies
是 get_dummies
的逆操作。
# 使用from_dummies还原分类变量
from_dummies_df = pd.from_dummies(dummies, sep='_')
print("\nFrom Dummies结果:\n", from_dummies_df)
6. 爆炸操作 (explode)
explode
将列表形式的元素拆分为多行。
# 创建包含列表的数据
df = pd.DataFrame({'ID': [1, 2],'Items': [['A', 'B'], ['C', 'D', 'E']]
})# 使用explode进行爆炸
exploded = df.explode('Items')
print("\nExplode结果:\n", exploded)
输出:
ID Items
0 1 A
0 1 B
1 2 C
1 2 D
1 2 E
7. 交叉表 (crosstab)
crosstab
计算两个或多个因素的简单交叉表。
# 创建示例数据
data = {'Gender': ['Male', 'Female', 'Male', 'Female', 'Male'],'Preference': ['Yes', 'No', 'Yes', 'Yes', 'No']
}
df = pd.DataFrame(data)# 使用crosstab创建交叉表
cross_tab = pd.crosstab(df['Gender'], df['Preference'])
print("\nCrosstab结果:\n", cross_tab)
输出:
Preference No Yes
Gender
Female 1 1
Male 1 2
8. 分箱操作 (cut)
cut
将连续变量离散化为区间。
# 创建连续数据
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]# 使用cut进行分箱
bins = [18, 25, 35, 60, 100]
labels = ['18-25', '26-35', '36-60', '61+']
age_groups = pd.cut(ages, bins=bins, labels=labels)
print("\nCut结果:\n", age_groups)
9. 因子化操作 (factorize)
factorize
将分类变量编码为数值。
# 创建分类数据
colors = ['red', 'blue', 'green', 'blue', 'red']# 使用factorize进行编码
codes, uniques = pd.factorize(colors)
print("\nFactorize结果:")
print("编码:", codes)
print("唯一值:", uniques)
输出:
编码: [0 1 2 1 0]
唯一值: ['red' 'blue' 'green']
10. 总结
-
透视表操作:
pivot
: 简单的长转宽操作,不支持聚合pivot_table
: 支持聚合的透视表,适合处理重复值
-
堆叠操作:
stack
: 将列转换为行,产生多级索引unstack
: 将行转换为列,是stack的逆操作
-
融合操作:
melt
: 将宽格式数据转换为长格式wide_to_long
: 更灵活的宽变长转换方法
-
虚拟变量转换:
get_dummies
: 将分类变量转换为虚拟变量from_dummies
: 将虚拟变量转换回分类变量
-
爆炸操作:
explode
: 将列表形式的元素拆分为多行
-
交叉表:
crosstab
: 计算两个或多个因素的简单交叉表
-
分箱操作:
cut
: 将连续变量离散化为区间
-
因子化操作:
factorize
: 将分类变量编码为数值
选择合适的数据变形方法取决于:
- 数据的原始结构和目标结构
- 是否需要聚合操作
- 是否需要处理重复值或列表数据
掌握这些数据变形与重塑技术将大大提高你在实际数据分析工作中的效率和灵活性,使你能轻松应对各种数据格式转换需求。