在 pandas 中,如何在多索引的第 2 级重新索引(填充 0)

Sum*_*mer 3 missing-data multi-index dataframe pandas reindex

我有一个数据帧数据透视表,有 2 个索引级别:月份和评级。评级应为 1、2、3(不要与列 1、2、3 混淆)。我发现有几个月,评级可能会丢失。例如,(人口和 2021-10)仅具有评级 1,2。我需要每个月都有收视率1、2、3。所以我需要将缺失的评级索引填为0。

        tbl = pd.pivot_table(self.df, values=['ID'], index=['month', 'risk'],
                             columns=["Factor"], aggfunc='count', fill_value=0)
        tbl = tbl.droplevel(None, axis=1).rename_axis(None, axis=1).rename_axis(index={'month': None,
                                                                                       'Risk': 'Client Risk Rating'})

# show Low for rating 1, Moderate for rating 2, Potential High for rating 3
    rating = {1: 'Low',
              2: 'Moderate',
              3: 'Potential High'
              }
    pop = {'N': 'Refreshed Clients', 'Y': 'Population'}
        tbl.rename(index={**rating,**pop}, inplace=True)
        tbl = tbl.applymap(lambda x: x.replace(',', '')).astype(np.int64)
        tbl = tbl.div(tbl.sum(axis=1), axis=0)
        # client risk rating may be missing (e.g., only 1,2). 
        # To draw, need to fill the missing client risk rating with 0 
        print("before",tbl)
        tbl=tbl.reindex(pd.MultiIndex.from_product(tbl.index.levels), fill_value=0)
        print("after pd.MultiIndex.from_product",tbl)
Run Code Online (Sandbox Code Playgroud)

我使用过 pd.MultiIndex.from_product。当所有数据都缺少一个索引时,它不起作用。例如,人口为中等,2021-03 和 2021-04 为低和中等。在 pd.MultiIndex.from_product 之后,人口数量有低和中等,但都缺少高。我的问题是每个月都有风险1、2、3。看来索引值来自数据。 在此输入图像描述

在此输入图像描述

在此输入图像描述

Cor*_*ien 5

您可以使用pd.MultiIndex.from_product创建完整索引:

>>> df
                             1         2         3
(Population)       1  0.436954  0.897747  0.387058
                   2  0.464940  0.611953  0.133941
2021-08(Refreshed) 1  0.496111  0.282798  0.048384
                   2  0.163582  0.213310  0.504647
                   3  0.008980  0.651175  0.400103

>>> df.reindex(pd.MultiIndex.from_product(df.index.levels), fill_value=0)
                             1         2         3
(Population)       1  0.436954  0.897747  0.387058
                   2  0.464940  0.611953  0.133941
                   3  0.000000  0.000000  0.000000  # New record
2021-08(Refreshed) 1  0.496111  0.282798  0.048384
                   2  0.163582  0.213310  0.504647
                   3  0.008980  0.651175  0.400103
Run Code Online (Sandbox Code Playgroud)

更新

我想知道df=df.reindex([1,2,3],level='rating',fill_value=0)不起作用,因为新的索引值 [1,2,3] 无法填充先前评级索引的缺失值。通过使用 from_product,它创建两个索引的乘积。

事实上它是有效的。我的意思是它有效果,但不是你期望的效果。该方法重新索引级别而不是。我来给你展示:

# It seems there is not effect because you don't see 3 and 4 as expected?
>>> df.reindex([1, 2, 3, 4], level='ratings')
                                   0         1         2
                   ratings                              
(Population)       1        0.536154  0.671380  0.839362
                   2        0.729484  0.512379  0.440018
2021-08(Refreshed) 1        0.279990  0.295757  0.405536
                   2        0.864217  0.798092  0.144219
                   3        0.214566  0.407581  0.736905

# But yes something happens
>>> df.reindex([1, 2, 3, 4], level='ratings').index.levels
FrozenList([['(Population)', '2021-08(Refreshed)'], [1, 2, 3, 4]])
                              The level has been reindexed ---^

# It's different from values
>>> df.reindex([1, 2, 3, 4], level='ratings').index.get_level_values('ratings')
Int64Index([1, 2, 1, 2, 3], dtype='int64', name='ratings')
Run Code Online (Sandbox Code Playgroud)