Pandas:更改多索引系列的重复项

Pandas: Change duplicates respecting multiindex series

以这个多指数系列为例:

client_id  y-m    
0          2018-05       13.935563
           2018-06     5326.898967
           2018-07    11968.431680
           2018-08             NaN
           2018-09             NaN
           2018-10    15257.418813
           2018-11             NaN
           2018-12    20509.774900
           2019-01    25187.485960
           2019-02             NaN
           2019-03             NaN
           2019-04             NaN
           2019-05             NaN
           2019-06             NaN
           2019-07             NaN
           2019-08    35943.419296
           2019-09    38253.756910
           2019-10    42289.134021
           2019-11             NaN
           2019-12             NaN
           2020-01             NaN
           2020-02             NaN
           2020-03             NaN
           2020-11             NaN
           2020-12             NaN
           2021-01             NaN
1          2019-07      169.805400
           2019-08      169.805400
           2019-09      169.805400
           2019-10      169.805400
           2019-11      169.805400
           2019-12             NaN
           2020-01             NaN
           2020-07             NaN
           2020-08             NaN
           2021-01             NaN

考虑到第一个索引 client_id,我想用 NaN 替换重复值,同时保持第一个值。重要的是只替换第一级索引的重复项。

对于上面的示例数据,client_id == 1的重复值序列应仅保留2019-07的值,其他应设置为NaN,如下所示:

1          2019-07      169.805400
1          2019-08             NaN
1          2019-09             NaN
1          2019-10             NaN

如果重复的值是连续的,则可以按第一个索引分组并使用shift。这将为您提供一个布尔掩码,可用于将重复值设置为 NaN。

代码:

mask = s.groupby('client_id').shift() == s
s.loc[mask] = np.nan

如果不能保证重复项是连续的,那么您可以先对值进行排序并应用上述解决方案:

s = s.sort_values()
mask = s.groupby('client_id').shift() == s
s.loc[mask] = np.nan
s = s.sort_index()

然后按索引排序return到原来的顺序。

另一种解决方案是将 duplicated 应用于每个组:

s.loc[s.groupby('client_id').apply(lambda x: x.duplicated(keep='first'))] = np.nan

所有解决方案的结果将是:

client_id  y-m    
0          2018-05       13.935563
           2018-06     5326.898967
           2018-07    11968.431680
           2018-08             NaN
           2018-09             NaN
           2018-10    15257.418813
           2018-11             NaN
           2018-12    20509.774900
           2019-01    25187.485960
           2019-02             NaN
           2019-03             NaN
           2019-04             NaN
           2019-05             NaN
           2019-06             NaN
           2019-07             NaN
           2019-08    35943.419296
           2019-09    38253.756910
           2019-10    42289.134021
           2019-11             NaN
           2019-12             NaN
           2020-01             NaN
           2020-02             NaN
           2020-03             NaN
           2020-11             NaN
           2020-12             NaN
           2021-01             NaN
1          2019-07      169.805400
           2019-08             NaN
           2019-09             NaN
           2019-10             NaN
           2019-11             NaN
           2019-12             NaN
           2020-01             NaN
           2020-07             NaN
           2020-08             NaN
           2021-01             NaN