Indexing 熊猫数据帧:在执行涉及两个数据帧的算术运算时,如何在多个索引级别上进行匹配

Indexing 熊猫数据帧:在执行涉及两个数据帧的算术运算时,如何在多个索引级别上进行匹配,indexing,dataframe,match,pandas,hierarchical,Indexing,Dataframe,Match,Pandas,Hierarchical,我有一个数据框架,主索引上有三个级别: from pandas import * df_multi = DataFrame(np.random.rand(6,2), index = [['CF', 'CF', 'CF', 'DA', 'DA','DA'], ['x', 'y', 'y', 'x', 'y', 'y'], ['a', 'b', 'a', 'a', 'a', 'b']], columns = ['PC1', 'PC2']) df_multi.index.names =['l1','l

我有一个数据框架,主索引上有三个级别:

from pandas import *
df_multi = DataFrame(np.random.rand(6,2), index = [['CF', 'CF', 'CF', 'DA', 'DA','DA'], ['x', 'y', 'y', 'x', 'y', 'y'], ['a', 'b', 'a', 'a', 'a', 'b']], columns = ['PC1', 'PC2'])
df_multi.index.names =['l1','l2','l3']

In [5]: df_multi
Out[5]: 
       PC1       PC2
l1 l2 l3                    
CF x  a   0.118061  0.473159
   y  b   0.159534  0.407676
      a   0.466731  0.163322
DA x  a   0.152799  0.333438
   y  a   0.632725  0.965348
      b   0.737112  0.834592
现在我想在第三层求和,然后将每个元素除以其相应的和,以得到第三层的份额(例如,将
(CF,x,a)
除以
(CF,x,a)
(CF,y,a)
除以
(CF,y,a)+(CF,y,b)
,等等)

然而,这不起作用。我正在寻找一个通用的解决方案,不局限于百分比份额的计算,它使我能够在多个层次上进行算术匹配。当只使用一个级别时,它确实有效,例如

df_multi = DataFrame(np.random.rand(4,2), index = [['CF', 'CF', 'DA', 'DA'], ['1', '2', '1', '2']], columns = ['PC1', 'PC2'])

df_single = DataFrame(np.random.rand(3,3), index = ['1', '2', '3'], columns = ['PC1', 'PC2', 'PC3'])

df_combined = df_multi.mul(df_single, level = 1)

这听起来像是
transform
的工作

df_multi.groupby(level=[0,1]).transform(lambda x: x/x.sum())
有关文件:

谢谢你,艾伦。我进一步研究了.apply和.transform。然而,这似乎允许在组级别执行功能。这是针对我的特殊情况的解决方案。然而,我很高兴找到一个更通用的解决方案,允许我添加dataframe1和dataframe2,在这里我不仅匹配一个级别的多索引,而且匹配多个级别的索引。例如,dataframe1有3个级别,dataframe2有两个级别,我想添加两个dataframe2,将dataframe2的两个级别与dataframe1的第二和第三个级别匹配,并沿dataframe1的第一个级别进行广播。
df_multi = DataFrame(np.random.rand(4,2), index = [['CF', 'CF', 'DA', 'DA'], ['1', '2', '1', '2']], columns = ['PC1', 'PC2'])

df_single = DataFrame(np.random.rand(3,3), index = ['1', '2', '3'], columns = ['PC1', 'PC2', 'PC3'])

df_combined = df_multi.mul(df_single, level = 1)
df_multi.groupby(level=[0,1]).transform(lambda x: x/x.sum())