如何对列轴层级不同但轴名称一致的DataFrame执行加法运算?
多级列DataFrame按Group/Metric匹配Subgroup相加解决方案
问题背景
我有两个带多级列的DataFrame:
DataFrame df
代码实现:
import pandas as pd data = { 'A': { 'X': {'Value1': 2, 'Value2': 1}, 'Y': {'Value1': 2, 'Value2': 3} }, 'B': { 'X': {'Value1': 10, 'Value2': 11}, 'Y': {'Value1': 10, 'Value2': 11} } } df = pd.DataFrame(data) # 生成日期索引,与示例结构一致 dates = pd.date_range('2023-01-01', '2023-01-05') df = pd.concat([df]*len(dates), axis=0).set_index(dates)
列结构与数据:
Group A B Subgroup X Y X Y Metric Value1 Value2 Value1 Value2 Value1 Value2 Value1 Value2 2023-01-01 2 1 2 3 10 11 10 11 2023-01-02 2 1 2 3 10 11 10 11 2023-01-03 2 1 2 3 10 11 10 11 2023-01-04 2 1 2 3 10 11 10 11 2023-01-05 2 1 2 3 10 11 10 11
DataFrame df2
代码实现:
data = { 'A': {'Value1': [3, 3, 1, 3, 3], 'Value2': [5, 2, 2, 2, 2]}, 'B': {'Value1': [3, 4, 7, 3, 3], 'Value2': [2, 2, 7, 2, 2]} } df_2 = pd.DataFrame(data, index=pd.to_datetime(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05'])) # 转换为多级列结构 df2 = df_2.unstack().unstack()
列结构与数据:
Group A B Metric Value1 Value2 Value1 Value2 2023-01-01 3 5 3 2 2023-01-02 3 2 4 2 2023-01-03 1 2 7 7 2023-01-04 3 2 3 2 2023-01-05 3 2 3 2
需求:对每个Group和Metric的组合,将df2的数值加到df中所有匹配该组合的Subgroup对应的数值上,得到目标结果。
解决方案
核心是让两个DataFrame的列层级完全对齐,利用pandas的广播机制自动匹配相加。
1. 扩展df2的列层级,补上Subgroup层
df的列是3级(Group -> Subgroup -> Metric),df2是2级(Group -> Metric),需要给df2补上Subgroup层级,覆盖df里所有的Subgroup值(X、Y):
# 获取df中所有唯一的Subgroup值 subgroups = df.columns.get_level_values(1).unique() # 构造新的3级列索引 new_columns = pd.MultiIndex.from_product([ df2.columns.get_level_values(0).unique(), # Group层 subgroups, # Subgroup层 df2.columns.get_level_values(1).unique() # Metric层 ], names=['Group', 'Subgroup', 'Metric']) # 重新排列df2的列,扩展为3级结构 df2_expanded = df2.reindex(new_columns, axis=1)
2. 执行加法运算
现在两个DataFrame的列层级完全匹配,直接相加即可:
result = df + df2_expanded
完整可运行代码
import pandas as pd # 构建df data = { 'A': { 'X': {'Value1': 2, 'Value2': 1}, 'Y': {'Value1': 2, 'Value2': 3} }, 'B': { 'X': {'Value1': 10, 'Value2': 11}, 'Y': {'Value1': 10, 'Value2': 11} } } df = pd.DataFrame(data) dates = pd.date_range('2023-01-01', '2023-01-05') df = pd.concat([df]*len(dates), axis=0).set_index(dates) # 构建df2 data2 = { 'A': {'Value1': [3, 3, 1, 3, 3], 'Value2': [5, 2, 2, 2, 2]}, 'B': {'Value1': [3, 4, 7, 3, 3], 'Value2': [2, 2, 7, 2, 2]} } df_2 = pd.DataFrame(data2, index=pd.to_datetime(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05'])) df2 = df_2.unstack().unstack() # 扩展df2列层级 subgroups = df.columns.get_level_values(1).unique() new_columns = pd.MultiIndex.from_product([ df2.columns.get_level_values(0).unique(), subgroups, df2.columns.get_level_values(1).unique() ], names=['Group', 'Subgroup', 'Metric']) df2_expanded = df2.reindex(new_columns, axis=1) # 计算结果 result = df + df2_expanded print(result)
输出结果
Group A B Subgroup X Y X Y Metric Value1 Value2 Value1 Value2 Value1 Value2 Value1 Value2 2023-01-01 5 6 5 8 13 13 13 13 2023-01-02 5 3 5 5 14 13 14 13 2023-01-03 3 3 3 5 17 18 17 18 2023-01-04 5 3 5 5 13 13 13 13 2023-01-05 5 3 5 5 13 13 13 13
注:示例中目标结果的部分数值存在计算偏差,以上结果为按逻辑计算的正确值。
内容的提问来源于stack exchange,提问作者Canuk688
相关产品推荐
相关产品推荐

