如何重新索引 MultiIndex 数据帧

Posted

技术标签:

【中文标题】如何重新索引 MultiIndex 数据帧【英文标题】:How to reindex a MultiIndex dataframe 【发布时间】:2019-04-16 15:11:46 【问题描述】:

有没有办法重新索引两个(不同级别的)数据帧,以便它们在所有级别共享一个公共索引?

演示:

创建一个名为“A”的基本数据框:

index = np.array(['AUD','BRL','CAD','EUR','INR'])
data = np.random.randint(1, 20, (5,5))
A = pd.DataFrame(data=data, index=index, columns=index)  

创建一个名为“B”的多索引数据框:

np.random.seed(42)
midx1 = pd.MultiIndex.from_product([['Bank_1', 'Bank_2'], 
['AUD','CAD','EUR']], names=['Bank', 'Curency'])
B = pd.DataFrame(np.random.randint(10,25,6), midx1)
B.columns = ['Notional']

基本 DF:

>>> Dataframe A:

        AUD     BRL     CAD     EUR     INR
AUD     7       19      11      11      4
BRL     8       3       2       12      6
CAD     2       1       12      12      17
EUR     10      16      15      15      19
INR     12      3       5       19      7

多索引 DF:

>>> Dataframe B:

                    Notional
Bank    Curency     
Bank_1  AUD         16
        CAD         13
        EUR         22
Bank_2  AUD         24
        CAD         20
        EUR         17

目标是:

1) 重新索引 B,使其货币级别包括 A 索引中的每种货币。 B 然后看起来像这样(请参阅包括 BRL 和 INR,它们的名义值并不重要):

                    Notional
Bank    Curency     
Bank_1  AUD         16
        CAD         13
        EUR         22
        BRL         0
        INR         0
Bank_2  AUD         24
        CAD         20
        EUR         17
        BRL         0
        INR         0

2) 重新索引 A 以便它包含 B 索引的第一级中的每个银行。 A 将如下所示:

               AUD      BRL     CAD     EUR     INR
Bank_1  AUD     7       19      11      11      4
        BRL     8       3       2       12      6
        CAD     2       1       12      12      17
        EUR     10      16      15      15      19
        INR     12      3       5       19      7
Bank_2  AUD     7       19      11      11      4
        BRL     8       3       2       12      6
        CAD     2       1       12      12      17
        EUR     10      16      15      15      19
        INR     12      3       5       19      7

这个应用程序将在更大的数据帧上,所以我需要一个 Python 的方法来做到这一点。

对于上下文,最终我想将 A 和 B 相乘。我正在尝试重新索引以获得匹配的索引,因为这被显示为一种将各种索引级别的数据帧相乘的干净方法: Pandas multiply dataframes with multiindex and overlapping index levels

感谢您的帮助。

【问题讨论】:

【参考方案1】:

使用reindex获取B

B.reindex( pd.MultiIndex.from_product([B.index.levels[0], 
A.index], names=['Bank', 'Curency']),fill_value=0)

Out[62]: 
                Notional
Bank   Curency          
Bank_1 AUD            16
       BRL             0
       CAD            13
       EUR            22
       INR             0
Bank_2 AUD            24
       BRL             0
       CAD            20
       EUR            17
       INR             0

使用concat获取A

pd.concat([A]*2,keys=B.index.levels[0])
Out[69]: 
            AUD  BRL  CAD  EUR  INR
Bank                               
Bank_1 AUD   10    5   10   14    1
       BRL   17    1   14   10    8
       CAD    3    7    3   15    2
       EUR   17    1   15    2   16
       INR    7   15    6    7    4
Bank_2 AUD   10    5   10   14    1
       BRL   17    1   14   10    8
       CAD    3    7    3   15    2
       EUR   17    1   15    2   16
       INR    7   15    6    7    4

【讨论】:

另外,您可以使用get_level_values,而不是硬编码['Bank_1', 'Bank_2'],就像这样B.index.get_level_values(0).unique() 工作 - 谢谢你们!正如我上面提到的最终我想将 A 和 B 相乘。我认为分别为 A 和 B 创建了由 5x5 矩阵和 5x1 矩阵组成的数据帧,我可以将它们相乘,但是,A.multiply(B) 不起作用.我想将 B 中的名义金额乘以 A 中的每个货币行。例如16*10、0*5、13*10、22*14、0*1 等。最终的形状将与 A 相同。如果这个问题太复杂,请告诉我,我将创建一个新条目。 对于大数据和大量级别 MultiIndex.from_product 通常是不可行的,因为计算限制是预期的新索引的组合键远少于数组的笛卡尔积结果。

以上是关于如何重新索引 MultiIndex 数据帧的主要内容,如果未能解决你的问题,请参考以下文章

如何使用基于整数位置的索引访问 MultiIndex 数据帧中的行

从具有包含 NaN 的 MultiIndex 索引的数据帧中获取值

按特定索引值过滤具有 MultiIndex 的数据帧 [重复]

如何使用 MultiIndex 重新索引?

将多个键上的 pandas 数据帧映射为列或 multiIndex

Python Pandas Multiindex Slicing/Indexing 获取重复数据