You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pandas按公共索引计算两个DataFrame列比值的报错处理

报错原因

将classif1、classif2设为多层索引后,df1的索引组合存在重复值:同一组classif1+classif2会同时对应SEX_M、SEX_F两条记录,而df2的同组索引是唯一值(仅对应SEX_T维度的汇总值)。pandas做索引对齐的算术运算时,不允许非唯一的多层索引直接做匹配计算,因此抛出ValueError: cannot handle a non-unique multi-index!错误。

解决方法

两个DataFrame仅需按classif1、classif2两个字段匹配对应总数值,不需要对齐sex字段,也不需要强行设置公共索引做运算,以下两种写法都可以直接得到正确结果:

  • 方法1:映射匹配(运算效率更高)
    把df2转为「(classif1, classif2) : obs_value」的字典,逐行匹配做除法即可,不需要修改原表结构:
# 构建分组到总数值的映射
total_value_map = df2.set_index(['classif1', 'classif2'])['obs_value'].to_dict()
# 逐行匹配计算占比
df1['Percentage_of_total'] = df1.apply(
    lambda x: x['obs_value'] / total_value_map[(x['classif1'], x['classif2'])],
    axis=1
)
  • 方法2:表合并后计算(逻辑更直观)
    先把df2的数值列重命名后,按两个公共维度左连接到df1,计算完占比后删掉临时的总数值列即可:
# 提取df2需要的字段并重命名数值列
df2_ref = df2[['classif1', 'classif2', 'obs_value']].rename(columns={'obs_value': 'total_obs'})
# 左连接匹配总数值
df1 = df1.merge(df2_ref, on=['classif1', 'classif2'], how='left')
# 计算占比
df1['Percentage_of_total'] = df1['obs_value'] / df1['total_obs']
# 删除临时列
df1.drop(columns='total_obs', inplace=True)

两种方法运行后得到的Percentage_of_total列结果完全一致,比如SEX_M+ECO_SECTOR_TOTAL的占比约为0.659,SEX_F+ECO_SECTOR_TOTAL的占比约为0.341,符合分性别数值除以总数值的计算逻辑。

内容的提问来源于stack exchange,提问作者A.N.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 03:30:51