Pandas如何构造二维以上数据结构以高效生成任意指定月份账单DataFrame
账单生成实现方案
方案1:多层索引DataFrame(推荐优先使用)
将三个DataFrame合并为多层列索引结构,一次构建后可快速查询任意月份/产品的任意指标,同时支持跨维度统计:
# 优先修正原代码变量名问题:不要用内置函数range做变量名,避免后续报错 date_range = pd.date_range('2020-01-31', periods=12, freq='M') column_names = list('ABCDEFGH') # 原数据生成逻辑不变 np.random.seed(0) quantities = pd.DataFrame(np.random.randint(0,100,size=(12, 8)), index=date_range, columns=column_names) unit_costs = pd.DataFrame(np.random.rand(12, 8), index=date_range, columns=column_names) costs = quantities*unit_costs # 合并为多层索引DataFrame,第一层列为指标类型,第二层为产品标识 all_bill_data = pd.concat( [quantities, unit_costs, costs], keys=['quantity', 'unit_cost', 'cost'], axis=1 ) # 封装查询函数 def get_bill(date): """ date支持传入日期字符串/时间戳/行偏移量 示例:get_bill('2020-01-31') 或 get_bill(0) 都可返回1月账单 """ return all_bill_data.iloc[date] if isinstance(date, int) else all_bill_data.loc[date].unstack(level=0)
调用示例:get_bill(0)返回的结果和你示例中的bill0完全一致。
方案2:账单数组实现
按你提到的思路,提前把所有月份的账单生成后存入列表,适合需要批量处理全量账单的场景:
bill_list = [] for month_idx in range(len(quantities)): month_bill = pd.DataFrame({ 'quantity': quantities.iloc[month_idx], 'unit_cost': unit_costs.iloc[month_idx], 'cost': costs.iloc[month_idx] }) bill_list.append(month_bill)
调用示例:bill_list[0]即可获取第一个月的账单。
方案3:动态生成函数(轻量化选择)
如果不需要提前存储全量账单,直接封装函数实时生成即可,不需要额外占用存储空间,查询速度也足够满足绝大多数场景:
def get_bill(date): if isinstance(date, int): q = quantities.iloc[date] u = unit_costs.iloc[date] else: q = quantities.loc[date] u = unit_costs.loc[date] return pd.DataFrame({'quantity': q, 'unit_cost': u, 'cost': q*u})
方案选择建议
- 日常查询使用优先选方案1,除了单月账单查询外,还支持直接做跨维度统计,比如计算产品A全年总成本只需执行
all_bill_data['cost']['A'].sum() - 若需要批量导出/处理所有月份账单,选方案2
- 若仅偶尔查询账单,不想额外存储中间数据,选方案3
内容的提问来源于stack exchange,提问作者Todd Houstein
相关产品推荐
相关产品推荐

