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']) # 指定多个分组指标和参与列
本文为原创文章,转载请标明出处