如何无需循环将df_test数据作为索引提取多重索引DataFrame的值
无循环从多级索引DataFrame匹配取值的解决方案
需求说明
现有多级列索引的DataFrame df_multi,以及包含匹配条件的df_test,需要用df_test中的Region(行索引)、Enseigne和boucherie(列的两级索引)作为匹配条件,从df_multi中取值并填充到df_test的taux列,要求不使用循环。
可行解决方案
方法1:使用DataFrame.lookup(最简洁)
lookup方法专为按行-列标签对取值设计,完美适配该场景:
# 构造列的元组列表,对应(Enseigne, boucherie)的组合 cols = list(zip(df_test['Enseigne'], df_test['boucherie'])) # 批量匹配取值并赋值 df_test['taux'] = df_multi.lookup(df_test['Region'], cols)
方法2:转成长格式后合并(逻辑最直观)
将df_multi转换为每行对应一个完整匹配组合的长表,再通过合并关联取值:
# 把多级列索引转为行索引,再重置为普通列 df_multi_long = df_multi.stack(level=[0, 1]).reset_index() df_multi_long.columns = ['Region', 'Enseigne', 'boucherie', 'taux'] # 合并df_test和转换后的表,自动匹配对应值 df_test = df_test.merge(df_multi_long, on=['Region', 'Enseigne', 'boucherie'], how='left')
方法3:通过索引定位批量取值(性能最优)
利用索引位置定位,结合numpy批量提取值,适合大数据量场景:
# 获取每个Region在df_multi行索引中的位置 row_pos = df_multi.index.get_indexer(df_test['Region']) # 获取每个(Enseigne, boucherie)在df_multi列索引中的位置 col_pos = df_multi.columns.get_indexer(list(zip(df_test['Enseigne'], df_test['boucherie']))) # 批量提取对应位置的值 df_test['taux'] = np.take_along_axis(df_multi.values, col_pos[None, :], axis=1)[row_pos, np.arange(len(df_test))]
验证结果
三种方法最终得到的df_test结果一致:
Region Enseigne boucherie taux 0 Est huit LS 52.47 1 Est contact Traditionnelle 57.45 2 Sud Est contact LS 66.10 3 Sud Ouest express LS 63.87
内容的提问来源于stack exchange,提问作者Théo M
相关产品推荐
相关产品推荐

