pandas.pivot()
是用于将数据重新整形的一种方法。它可以根据数据的列将数据从长格式(long format)转为宽格式(wide format)。简单来说,它会基于指定的索引列、列标头和数据值将表格 “旋转” 或重排,生成一个新的 DataFrame。
⭐️ 语法:
pandas.pivot(data, index=None, columns=None, values=None)
⭐️ 参数:
- data:
DataFrame
,输入的数据集。 - index:用于指定行索引的列标签或列名。即“长格式”中的某列被重新排列到行索引位置。
- columns:用于生成列的新列名,通常是用来生成“宽格式”的列标头。
- values:指定要填充的数值列,即转到宽格式后,在新表中应该显示的数值。
⭐️ 返回:
- 返回一个 DataFrame,其中 index 是
index
参数指定的列,columns 是columns
参数指定的列,值是values
参数指定的列。
⭐️ 使用示例:
示例 1:简单的 pivot
使用
假设我们有一个包含销售数据的 DataFrame,如下所示:
import pandas as pd
# 创建示例数据
df = pd.DataFrame({
'date': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02'],
'product': ['A', 'B', 'A', 'B'],
'sales': [100, 200, 150, 250]
})
print(df)
输出:
date product sales
0 2023-01-01 A 100
1 2023-01-01 B 200
2 2023-01-02 A 150
3 2023-01-02 B 250
我们希望按照 date
作为行索引,product
作为列标,sales
作为值,将数据转换成宽格式:
df_pivot = df.pivot(index='date', columns='product', values='sales')
print(df_pivot)
输出:
product A B
date
2023-01-01 100.0 200.0
2023-01-02 150.0 250.0
示例 2:当 values
没有指定时
values
是可选参数。如果不指定 values
,pivot()
会返回一个新的 DataFrame,其中包含所有剩余列的数据。例如:
df = pd.DataFrame({
'date': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02'],
'product': ['A', 'B', 'A', 'B'],
'sales': [100, 200, 150, 250],
'profit': [30, 40, 50, 60]
})
# 不指定 values
df_pivot = df.pivot(index='date', columns='product')
print(df_pivot)
输出:
sales profit
product A B A B
date
2023-01-01 100 200 30 40
2023-01-02 150 250 50 60
这里,我们得到了一个包含 sales
和 profit
两个字段的多层列索引的 DataFrame。
示例 3:处理重复的条目
如果 index
和 columns
组合存在重复的条目,pivot()
会抛出 ValueError
。在这种情况下,你可以使用 pivot_table()
方法,它允许你在遇到重复项时执行聚合操作。
例如:
df = pd.DataFrame({
'date': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02', '2023-01-01'],
'product': ['A', 'B', 'A', 'B', 'A'],
'sales': [100, 200, 150, 250, 50]
})
# 使用 pivot 会报错
# df_pivot = df.pivot(index='date', columns='product', values='sales')
# 使用 pivot_table,求和聚合
df_pivot = df.pivot_table(index='date', columns='product', values='sales', aggfunc='sum')
print(df_pivot)
输出:
product A B
date
2023-01-01 150.0 200.0
2023-01-02 150.0 250.0
⭐️ 进阶:
这里展示pd.pivot在包含10个字段的原始数据上的应用,我们可以构造一个包含多种信息的DataFrame,比如销售数据,其中可能包括产品ID、地区、销售渠道、日期、销售量、销售额、成本、利润、折扣率和客户满意度等字段。不过,由于pd.pivot主要用于根据某些字段(通常是分类字段)来重新组织数据,我们通常会选择其中的几个字段作为index、columns和values。
代码如下:
import pandas as pd
import numpy as np
# 构造包含10个字段的原始数据
np.random.seed(0) # 为了可重复性设置随机种子
data = {
'ProductID': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A'],
'Region': ['East', 'East', 'West', 'East', 'West', 'West', 'East', 'West', 'East', 'West'],
'Channel': ['Online', 'Offline', 'Online', 'Offline', 'Online', 'Offline', 'Online', 'Online', 'Offline', 'Offline'],
'Date': ['2023-01-01'] * 10, # 简化处理,所有日期相同
'SalesVolume': np.random.randint(10, 100, 10),
'Revenue': np.random.randint(100, 1000, 10),
'Cost': np.random.randint(50, 500, 10),
'Profit': np.random.randint(10, 200, 10),
'DiscountRate': np.random.uniform(0.0, 0.5, 10),
'CustomerSatisfaction': np.random.uniform(0.0, 10.0, 10)
}
df = pd.DataFrame(data)
# 显示原始数据
print("原始数据:")
print(df)
# 使用pd.pivot重新组织数据
# 假设我们想要根据ProductID和Region来查看每个Channel的平均SalesVolume和Revenue
pivot_df = pd.pivot_table(df, values=['SalesVolume', 'Revenue'], index=['ProductID', 'Region'], columns='Channel', aggfunc='mean')
# 重置列的多级索引,以便更清晰地显示
pivot_df.columns = ['_'.join(col).rstrip('_') for col in pivot_df.columns.values]
# 显示透视后的数据
print("\n透视后的数据:")
print(pivot_df)
执行结果:
原始数据:
ProductID Region Channel Date SalesVolume Revenue Cost Profit DiscountRate CustomerSatisfaction
0 A East Online 2023-01-01 54 170 138 89 0.319961 6.176355
1 B East Offline 2023-01-01 57 572 387 185 0.071677 6.120957
2 C West Online 2023-01-01 74 700 215 92 0.472334 6.169340
3 A East Offline 2023-01-01 77 496 75 109 0.260924 9.437481
4 B West Online 2023-01-01 77 414 383 187 0.207331 6.818203
5 C West Offline 2023-01-01 19 805 122 39 0.132278 3.595079
6 A East Online 2023-01-01 93 586 315 157 0.387117 4.370320
7 B West Online 2023-01-01 31 651 454 157 0.228075 6.976312
8 C East Offline 2023-01-01 46 187 165 152 0.284217 0.602255
9 A West Offline 2023-01-01 97 274 293 177 0.009395 6.667667
透视后的数据:
Revenue_Offline Revenue_Online SalesVolume_Offline SalesVolume_Online
ProductID Region
A East 496.0 378.0 77.0 73.5
West 274.0 NaN 97.0 NaN
B East 572.0 NaN 57.0 NaN
West NaN 532.5 NaN 54.0
C East 187.0 NaN 46.0 NaN
West 805.0 700.0 19.0 74.0
⭐️ 总结:
pd.pivot()
用于将“长格式”的数据转化为“宽格式”,创建行和列的多重索引。- 可以指定行索引(
index
)、列(columns
)和需要填充的值(values
)。 - 当数据集中存在重复条目时,使用
pivot()
会报错,此时可以使用pivot_table()
结合聚合函数来处理。