Pandas multiply dataframes with multiindex and overlapping index levels

前端 未结 3 584
情书的邮戳
情书的邮戳 2021-01-01 16:28

I´m struggling with a task that should be simple, but it is not working as I thought it would. I have two numeric dataframes A and B with multiindex and columns below:

3条回答
  •  悲&欢浪女
    2021-01-01 17:09

    I'd simply use DF.reindex on the lesser shaped DF to match the index of that of the bigger DF's shape and forward fill the values present in it. Then do the multiplication.

    B.multiply(A.reindex(B.index, method='ffill'))             # Or method='pad'
    

    Demo:

    Prep up some data:

    np.random.seed(42)
    midx1 = pd.MultiIndex.from_product([['X', 'Y'], [1,2,3]])
    midx2 = pd.MultiIndex.from_product([['X', 'Y'], [1,2,3], ['a','b','c']])
    A = pd.DataFrame(np.random.randint(0,2,(6,4)), midx1, list('ABCD'))
    B = pd.DataFrame(np.random.randint(2,4,(18,4)), midx2, list('ABCD'))
    

    Small DF:

    >>> A
    
         A  B  C  D
    X 1  0  1  0  0
      2  0  1  0  0
      3  0  1  0  0
    Y 1  0  0  1  0
      2  1  1  1  0
      3  1  0  1  1
    

    Big DF:

    >>> B 
    
          A  B  C  D
    X 1 a  3  3  3  3
        b  3  3  2  2
        c  3  3  3  2
      2 a  3  2  2  2
        b  2  2  3  3
        c  3  3  3  2
      3 a  3  3  2  3
        b  2  3  2  3
        c  3  2  2  2
    Y 1 a  2  2  2  2
        b  2  3  3  2
        c  3  3  3  3
      2 a  2  3  2  3
        b  3  3  2  3
        c  2  3  2  3
      3 a  2  2  3  2
        b  3  3  3  3
        c  3  3  3  3
    

    Multiplying them after making sure both share a common index axis across all levels:

    >>> B.multiply(A.reindex(B.index, method='ffill'))
    
           A  B  C  D
    X 1 a  0  3  0  0
        b  0  3  0  0
        c  0  3  0  0
      2 a  0  2  0  0
        b  0  2  0  0
        c  0  3  0  0
      3 a  0  3  0  0
        b  0  3  0  0
        c  0  2  0  0
    Y 1 a  0  0  2  0
        b  0  0  3  0
        c  0  0  3  0
      2 a  2  3  2  0
        b  3  3  2  0
        c  2  3  2  0
      3 a  2  0  3  2
        b  3  0  3  3
        c  3  0  3  3
    

    Now you can even supply the level parameter in DF.multiply for broadcasting to occur at those matching indices.

提交回复
热议问题