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

Posted

技术标签:

【中文标题】Pandas:根据多索引系列更改重复项【英文标题】:Pandas: Change duplicates respecting multiindex series 【发布时间】:2021-06-09 23:52:57 【问题描述】:

参加这个多索引系列:

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

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

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

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

【问题讨论】:

【参考方案1】:

如果重复值是连续的,则可以按第一个索引分组并使用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()

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

另一种解决方案是将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

【讨论】:

解决了!但是,如果值在 client_id 中重复,但不是连续的,这是否也会起作用? @DanielArges:不,原始解决方案假定重复值是有序的。我添加了两个替代解决方案,它们也适用于非连续情况。

以上是关于Pandas:根据多索引系列更改重复项的主要内容,如果未能解决你的问题,请参考以下文章

使用索引值列表对 pandas 多索引数据框进行切片 [重复]

在 pandas 多索引数据帧上绘制两个级别的 x_ticklabels [重复]

取消堆叠具有重复项的多索引

具有重复值的 Python 多索引切片

在 groupby 熊猫对象上应用 rolling() 时,多索引重复

无法正确组合多索引列(3 级)