如何用pandas pivot_table聚合多列并整理为目标格式?
问题描述
现有如下Pandas DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame( [ ['1990-01-01','A','S1','2','string2','string3'], ['1990-01-01','A','S2','1','string1','string4'], ['1990-01-01','A','S3','1','string5','string6'] ], columns=["date","type","status","count","s1","s2"] )
原始数据结构:
date type status count s1 s2 0 1990-01-01 A S1 2 string2 string3 1 1990-01-01 A S2 1 string1 string4 2 1990-01-01 A S3 1 string5 string6
需要得到的结果:每个date和type对应唯一一行,将status对应的count展开为单独列,同时计算s1列的全局最小值、s2列的全局最大值:
date type S1 S2 S3 min_s1 max_s2 1990-01-01 A 2 1 1 string1 string6
尝试用pivot_table实现,但返回了多层列结构,不符合预期格式:
df.pivot_table( index=['date','type'], columns=['status'], values=['count','s1','s2'], aggfunc={ 'count':np.sum, 's1': np.min, 's2': np.max } )
解决方案
拆分两步处理,先单独处理count的透视,再计算s1/s2的聚合值,最后合并结果,逻辑更清晰,结果完全符合要求:
- 透视
count列,将status转为列名:
count_df = df.pivot_table( index=['date', 'type'], columns='status', values='count', aggfunc=np.sum ).rename(columns=str).reset_index()
- 按
date和type分组,计算s1的最小值和s2的最大值:
agg_df = df.groupby(['date', 'type']).agg( min_s1=('s1', np.min), max_s2=('s2', np.max) ).reset_index()
- 合并两个结果集:
final_result = pd.merge(count_df, agg_df, on=['date', 'type'])
如果想更简洁,也可以用join方式合并:
# 先生成count透视表 final_result = df.pivot_table( index=['date', 'type'], columns='status', values='count', aggfunc=np.sum ).rename(columns=str).reset_index() # 计算聚合值并合并 agg_vals = df.groupby(['date', 'type'])[['s1', 's2']].agg( min_s1=('s1', 'min'), max_s2=('s2', 'max') ) final_result = final_result.join(agg_vals, on=['date', 'type'])
执行后就能得到扁平列结构的预期结果。
另外,若一定要用单次pivot_table,需要手动扁平化多层列,但这种方式会生成按status分组的s1/s2值,不是全局的聚合结果,还需要额外补充全局聚合列,不如拆分处理直观。
内容的提问来源于stack exchange,提问作者Niuya
相关产品推荐
相关产品推荐

