将两个多索引数据帧与不同但相似的索引和列相乘

时间:2020-02-03 17:21:45

标签: python pandas dataframe multi-index

请考虑这两个数据框。

import pandas as pd
cols = ['F', 'D']

s_ind = pd.MultiIndex.from_arrays([['A', 'A', 'A'], ['B', 'B', 'B'], ['C', 'C', 'C'], ['D', 'E', 'F']],
                                  names=('cat1', 'cat2', 'cat3', 'cat4'))
s = pd.DataFrame(data=[[1,4], [2,5], [3,6]], columns=cols, index=s_ind)

所以s是:


                      F  D
cat1 cat2 cat3 cat4      
A    B    C    D     1  4
               E     2  5
               F     3  6

和...

ib_ind = pd.MultiIndex.from_arrays([['A'], ['B'], ['C']], names=['cat1', 'cat2', 'cat3'])
ib = pd.DataFrame(data=[[7, 8]], columns=cols, index=ib_ind)

所以ib是:

                 F  D
cat1 cat2 cat3      
A    B    C     7  8

无论我使用轴0(显示)还是1(未显示)相乘,我都会收到相同的结果。看到这里:

print(ib.mul(s, axis=0))
                      F   D
cat1 cat2 cat3 cat4        
A    B    C    D      7  32
               E     14  40
               F     21  48

问题:如何执行乘法运算,以便将其作为输出接收?

print(pd.DataFrame(data=[[8*1,8*4], [0,0], [7*3,7*6]], columns=cols, index=s_ind))
                      F   D
cat1 cat2 cat3 cat4        
A    B    C    D      8  32
               E      0   0
               F     21  42

请注意,E行为0,因为ib中没有对应的E列要相乘。另外,nan也可以。

1 个答案:

答案 0 :(得分:4)

您可以将s的{​​{3}}和unstack ib与{{1}上的level=1一起尝试,然后再multiply stackaxis=1

fill_value=0

@piRSquared建议的另一种方法是只重塑一次(因此更快),即将要匹配的索引的索引reindex乘以final = ib.mul(s.unstack(),level=1,axis=1).stack().reindex(s.index,fill_value=0) # or: ib.mul(s.unstack('cat4'),level=1,axis=1).stack().reindex(s.index,fill_value=0) stack之后相乘:

reindex

s.mul(ib.rename_axis('cat4', axis=1).stack().reindex(s.index, fill_value=0), axis=0)