基于原列名在MultiIndex DataFrame中自动新增计算列并保留二级格式
自动为MultiIndex DataFrame生成差值与百分比变化列
解决方案代码
import numpy as np import pandas as pd # 原始数据初始化 data = [[99,3,12,4,63,55]] cols = pd.MultiIndex.from_product([['1. FY21','2. FY22','3. FY23'],['Values','Sites']]) df = pd.DataFrame(data, columns=cols) # 获取level0的财年列表(保留原始顺序) fy_list = cols.levels[0].tolist() # 设定基准财年(这里取最后一个财年FY23) base_fy = fy_list[-1] # 复制原始数据用于新增列 new_data = df.copy() # 存储新列的level0标签顺序 new_col_level0 = [] # 遍历每个非基准财年,计算差值和百分比变化 for fy in fy_list[:-1]: # 提取财年名称(去掉前面的序号) base_fy_name = base_fy.split('. ')[1] current_fy_name = fy.split('. ')[1] # 计算差值列 diff_col_name = f"{base_fy_name}-{current_fy_name}" new_data[(diff_col_name, 'Values')] = df[(base_fy, 'Values')] - df[(fy, 'Values')] new_data[(diff_col_name, 'Sites')] = df[(base_fy, 'Sites')] - df[(fy, 'Sites')] # 计算百分比变化列(转整数匹配示例输出) pct_col_name = f"{base_fy_name}-{current_fy_name}_ % Change" new_data[(pct_col_name, 'Values')] = ((df[(base_fy, 'Values')] - df[(fy, 'Values')]) / df[(fy, 'Values')] * 100).astype(int) new_data[(pct_col_name, 'Sites')] = ((df[(base_fy, 'Sites')] - df[(fy, 'Sites')]) / df[(fy, 'Sites')] * 100).astype(int) # 更新列顺序:原财年 → 差值列 → 百分比变化列 new_col_level0.extend([fy, diff_col_name, pct_col_name]) # 添加基准财年到列顺序末尾 new_col_level0.append(base_fy) # 构造新的MultiIndex列并重新排列数据 new_multi_cols = pd.MultiIndex.from_product([new_col_level0, ['Values', 'Sites']]) df_new = new_data[new_multi_cols] # 输出结果 print(df_new)
代码说明
- 财年列表提取:从原MultiIndex的level0获取所有财年标签,确保和原始列顺序一致。
- 基准财年设定:默认取最后一个财年作为对比基准,若需调整,直接修改
base_fy的值即可。 - 新增列计算:
- 差值列:以基准财年数值减去当前财年数值,列名自动生成为
基准财年-当前财年格式。 - 百分比变化列:计算差值相对于当前财年的百分比,乘以100后转为整数(匹配示例输出格式),列名自动生成为
基准财年-当前财年_ % Change格式。
- 差值列:以基准财年数值减去当前财年数值,列名自动生成为
- 列顺序重构:按照「原财年 → 差值列 → 百分比变化列」的逻辑重新构造MultiIndex,确保二级索引(Values/Sites)的格式完全保留。
输出验证
运行代码后得到的df_new与你提供的期望输出完全一致,自动完成所有列的计算与命名,无需手动定义每一列。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

