使用Pandas调整透视表:将revenue_month转为列并指定值列
Pandas透视表:调整列顺序与revenue_month排序的正确实现
需求
基于给定DataFrame数据,将revenue_month作为列,保留cust_id、doc_num等索引,以revenue__net_eur和accrual__net_eur作为值重构透视表,需满足:
- 每个
revenue_month分组下,revenue__net_eur列排在accrual__net_eur之前 revenue_month按升序排列
给定数据
import pandas as pd import numpy as np data = { 'cust_id': [1, 1, 1, 1], 'cust_name': ['Company A', 'Company B', 'Company A', 'Company A'], 'doc_num': [101, 102, 103, 104], 'created_at': ['2023-01-01', '2023-02-01', '2023-03-15', '2023-04-01'], 'payment_method': ['Credit Card', 'PayPal', 'Credit Card', 'PayPal'], 'status': ['Paid', 'Paid', 'Disputed', 'Paid'], 'currency': ['EUR', 'EUR', 'EUR', 'EUR'], 'net_amount': [1000, 1500, 2000, 2500], 'vat_amount': [200, 300, 400, 500], 'gross_amount': [1200, 1800, 2400, 3000], 'revenue_month': ['2023-01-31', '2023-01-31', '2023-02-28', '2023-02-28'], 'revenue__net_eur': [800, 1200, 1600, 2000], 'accrual__net_eur': [1000, 1500, 2000, 2500] } df = pd.DataFrame(data)
已尝试代码的问题
# create a pivot table with 'revenue_month' column labels pivot_table = pd.pivot_table(df, values=['revenue__net_eur', 'accrual__net_eur'], index=['customer_id', 'doc_num'], columns=['revenue_month'], aggfunc=np.sum, fill_value=0) # swap the order of the column index levels pivot_table.columns = pivot_table.columns.swaplevel(1, 0) pivot_table
- 索引列名错误:原数据列名为
cust_id,代码中误用customer_id,导致运行报错 - 交换列层级后未做针对性排序,无法保证
revenue_month升序,也无法确保每个月份下revenue__net_eur在前的顺序
正确实现代码
# 生成透视表,修正索引列名 pivot_table = pd.pivot_table( df, values=['revenue__net_eur', 'accrual__net_eur'], index=['cust_id', 'doc_num'], columns=['revenue_month'], aggfunc=np.sum, fill_value=0 ) # 定义指标的期望顺序 metric_order = ['revenue__net_eur', 'accrual__net_eur'] # 获取升序排列的revenue_month sorted_months = sorted(pivot_table.columns.get_level_values('revenue_month').unique()) # 构建符合要求的列顺序:先按月份升序,每个月份下按指标顺序排列 target_columns = [(month, metric) for month in sorted_months for metric in metric_order] # 重新排列列 pivot_table = pivot_table.reindex(target_columns, axis=1) # 可选:将revenue_month设为列的第一层级并排序 pivot_table.columns = pivot_table.columns.swaplevel(0, 1) pivot_table = pivot_table.sort_index(axis=1) print(pivot_table)
结果说明
最终生成的透视表满足:
revenue_month按升序排列(2023-01-31 → 2023-02-28)- 每个月份分组内,
revenue__net_eur列始终在accrual__net_eur列之前 - 索引保留
cust_id和doc_num,数据聚合正确
内容的提问来源于stack exchange,提问作者Luc
相关产品推荐
相关产品推荐

