【问题标题】:Multiplying two multiindex dataframes with different but similar indices and columns将具有不同但相似的索引和列的两个多索引数据帧相乘
【发布时间】:2020-05-19 12:01:51
【问题描述】:

请考虑这两个数据框。

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 列可以相乘。或者,nans 也可以。

【问题讨论】:

    标签: python pandas dataframe multi-index


    【解决方案1】:

    您可以尝试unstacksmultiply iblevel=1axis=1 ,然后stack 它返回和reindexfill_value=0

    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)
    

    @piRSquared 建议的另一种方法是仅重新整形一次(因此速度更快)是 rename 在相乘时要匹配的索引的索引,然后是 stackreindex 相乘后:

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

                            F     D
    cat1 cat2 cat3 cat4            
    A    B    C    D      8.0  32.0
                   E      0.0   0.0
                   F     21.0  42.0
    

    【讨论】:

    • 我会这样做。 s.mul(ib.rename_axis('cat4', axis=1).stack().reindex(s.index, fill_value=0), axis=0)
    • @piRSquared:我的解决方案与您的类似:s.mul(ib.stack().reindex(s.index, fill_value=0), axis=0) :)
    • @piRSquared ehh,,.. 不错,只有一次是重塑然后,我在想怎么做,可能会被unstack 卡住,谢谢 :) 我可以添加它吗?
    • @anky_91 请做
    猜你喜欢
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 2017-05-20
    • 2020-11-02
    相关资源
    最近更新 更多