如何修改Pandas透视表分箱范围为从0开始的累计区间?
解决方案:将Pandas透视表转换为累计订单数量统计
方案一:基于现有透视表计算累计值(高效)
这种方法直接利用你已生成的透视表,通过**累计求和(cumsum)**得到各时间点的累计订单量,无需修改原始数据处理流程,适合大数据量场景。
步骤说明:
- 你的现有透视表已按时间区间从早到晚排序,每个区间的订单量为独立统计值;
- 对每个订单类型(
today_qty/yesterday_qty),按时间顺序做累计求和,得到从0点到对应时间点的总订单量; - 将列标签替换为目标的累计区间格式。
完整代码:
import pandas as pd # 你的原始代码(生成初始透视表) df['Hour_Num'] = pd.cut(df.order_hour,[0,12,15,20,24]) pivot_df = df.pivot_table(index='channel_name', values=(['yesterday_qty','today_qty']), columns=['Hour_Num'], aggfunc=('sum')).fillna(0) pivot_df = pivot_df.swaplevel(0,1, axis=1).sort_index(axis=1) # 1. 按订单类型分组,执行累计求和 cumulative_pivot = pivot_df.groupby(level=1, axis=1).cumsum(axis=1) # 2. 替换列标签为累计区间格式 def get_interval_upper(interval): return interval.right # 提取区间的上限值 new_columns = pd.MultiIndex.from_tuples( [(f'(0, {get_interval_upper(interval)}]', qty) for interval, qty in cumulative_pivot.columns], names=['Hour_Num', 'qty'] ) cumulative_pivot.columns = new_columns # 输出结果 print(cumulative_pivot)
结果说明:
以Ajio为例,(0,15]的yesterday_qty会变为68+55=123,(0,20]变为123+53=176,(0,24]变为176+32=208,完全匹配累计统计需求。
方案二:从原始数据生成累计分组(直观)
这种方法通过扩展原始数据行,将每个订单分配到所有包含它的累计区间中,再重新生成透视表,逻辑更直观,适合数据量较小的场景。
步骤说明:
- 定义需要统计的累计时间点(12、15、20、24);
- 遍历每个订单,将其复制到所有满足
order_hour <= 时间点的区间行中; - 基于扩展后的数据集生成透视表,直接得到累计订单量。
完整代码:
import pandas as pd # 定义累计时间点的上限 thresholds = [12, 15, 20, 24] # 扩展原始数据:每个订单对应所有符合条件的累计区间 expanded_rows = [] for _, row in df.iterrows(): hour = row['order_hour'] for t in thresholds: if hour <= t: new_row = row.copy() new_row['Hour_Num'] = f'(0, {t}]' expanded_rows.append(new_row) expanded_df = pd.DataFrame(expanded_rows) # 生成累计透视表 cumulative_pivot = expanded_df.pivot_table( index='channel_name', values=['yesterday_qty', 'today_qty'], columns=['Hour_Num'], aggfunc='sum' ).fillna(0) # 调整列层级顺序(与原始代码一致) cumulative_pivot = cumulative_pivot.swaplevel(0, 1, axis=1).sort_index(axis=1) # 输出结果 print(cumulative_pivot)
内容的提问来源于stack exchange,提问作者Manas Ranjan
相关产品推荐
相关产品推荐

