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。看来索引值来自数据。

您可以使用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)