pandas之表的长宽转换

表格的长宽转换

表格长宽转换也是一种透视表操作

  • df.pivot()
    • 将 一张长表 转为 多张宽表
  • pd.melt()
    • 将 多张宽表 转为 一张长表

二者互为逆操作


pivot和pivot_table的区别

  • pivot转换后,如果表索引有重复值会直接出错
  • pivot_table转换后,如果表索引有重复值会聚合为一个输出,不会出错
    • 如果数据不重复,pivot_table得到的结果和pivot一致
    • pivot_table更常用
df_test = pd.DataFrame({
    'foo': ['one','one','one','two','two','two'],
    'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
    'baz': [1, 2, 3, 4, 5, 6]
})
df_test.pivot(index='foo', columns='bar', values='baz')  # 不带聚合
df_test.pivot_table(index='foo', columns='bar', values='baz')  # 带聚合,推荐

df_test = pd.DataFrame({
    'foo': ['one','one','one','one','two','two'],
    'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
    'baz': [1, 2, 3, 4, 5, 6]
})
df_test.pivot_table(index='foo', columns='bar', values='baz')
# df_test.pivot(index='foo', columns='bar', values='baz')  # 不带聚合,重复即出错(长宽表格转换)
总结:
重复指index,columns一致



将“长格式”旋转为“宽格式”:pivot()
将一列拆分为多列

1列值做行索引
1列值做列索引
剩下的值做表格值
多个时间序列数据通常是以所谓的“长格式”(long)或“堆叠格式”(stacked)存储在数据库和CSV中的
ldata = pd.read_csv('examples/pivot.csv', parse_dates=['date'])
ldata[:14]  # 1年,4个季度,3个指标,共12条数据
date	item	value	value2
0	1959-03-31	realgdp	2710.349	-0.492362
1	1959-03-31	infl	0.000	0.938709
2	1959-03-31	unemp	5.800	-1.249725
3	1959-06-30	realgdp	2778.801	-1.299523
4	1959-06-30	infl	2.340	-0.601390
5	1959-06-30	unemp	5.100	0.958452
6	1959-09-30	realgdp	2775.488	-1.239327
7	1959-09-30	infl	2.740	0.908910

# pivot()前两个参数是行和列索引,最后一个可选参数是需要拆分的列
ldata.pivot('date', 'item', 'value').head()
# 如果不加第三个参数,就会分拆除行、列索引外的所有列,大概率返回3维dataframe
ldata.pivot('date', 'item').head()
ldata.pivot('date', 'item')['value'].head()  # 同上


用分组聚合(groupby)和重塑(unstack)一般可以实现所有数据重塑功能
不使用新学的pivot方法,
将1天变成一行,item类别从1列变成3列
# 先把要选择的列变为行索引 两种方式
# 1 分组聚合重塑,min()用来保留原值的
ldata.groupby(['date', 'item'])['value'].min().unstack().head()  # 这里聚合运算返回的直接是原值
# 方法2,类似分组聚合
ldata.groupby(['date', 'item']).min().head()  # 分组聚合的方式
ldata.set_index(['date', 'item']).head()  # 将这两列转为行索引,效果同上
ldata.set_index(['date', 'item']).unstack()['value'].head()

将“宽格式”旋转为“长格式”

将多列合并为1列

pivot的逆运算是pandas.melt

它不是将一列转换到多个新的DataFrame,而是合并多个列成为一个,产生一个比输入长的DataFrame

df2 = pd.DataFrame({'key': ['foo', 'bar', 'baz'], 'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]})
# 可看性不好
dfx = pd.melt(df2)  # 将无论多少列转为2列,1列是原列索引,1列是原值

当使用pandas.melt,最好指明哪些列是分组指标
指定key列是唯一分组指标,其它列是数据值
melted = pd.melt(df2, ['key'])
xxx = melted.pivot('key', 'variable', 'value').reset_index()  # reset_index()将行索引转为普通列,set_index()普通列转为行索引
xxx.columns.name = ''  # 去除列索引name

# 还可以指定哪些列参与合并
pd.melt(df2, ['key'])
pd.melt(df2, ['key'], value_vars=['A', 'B'])  # 没有c

pandas.melt可以不用分组指标
pd.melt(df2, value_vars=['A', 'B'])

综合练习:同时指定多个分组指标,和参与列
pd.melt(df2, ['key','A'])  # 指定多个分组指标
pd.melt(df2, ['key','A'], value_vars=['B'])  # 指定多个分组指标和参与列

  

  

 

posted @ 2020-08-19 11:09  亚洲哈登  阅读(1328)  评论(0编辑  收藏  举报