【问题标题】:Pandas remove all 0s until first nonzero value within each level of multiindexPandas 删除所有 0,直到多索引的每个级别中的第一个非零值
【发布时间】:2020-01-11 17:34:00
【问题描述】:

我正在处理一个 pandas MultiIndex 数据集,其中许多不同的数据组(第 1 项、第 2 项等)都有 0。我只想删除 0 的行,其中 0 位于 Item 组的开头。如果 0 出现在非零数字之后,我不想删除它。如何删除所有零,直到每组中的第一个非零值(外部索引)?

原始数据

                          Quantity
Item1           2016-05-08  0.0
                2016-05-15  0.0
                2016-05-22  0.0
                2016-05-29  456
                2016-06-05   22
Item2           2018-03-08  0.0
                2018-03-15  300
                2018-03-21  0.0
                2018-03-29  0.0
                2018-03-05  433

期望的输出

                          Quantity
Item1           2016-05-29  456
                2016-06-05   22
Item2           2018-03-15  300
                2018-03-21  0.0
                2018-03-29  0.0
                2018-03-05  433

【问题讨论】:

  • 你的问题是什么?
  • @DYZ 见上文 - 我正在尝试将第一个输出转换为第二个
  • 这不是问题。 SO 是一个问答网站。您提出问题 - 我们会帮助您解答。
  • @DYZ 我声明“如何删除所有零,直到每个组中的第一个非零值(外部索引)?”我提供了一个例子。不清楚吗?
  • 现在你做到了:) 但后来你没有。

标签: python pandas pandas-groupby multi-index


【解决方案1】:

本质上是一个孤岛和差距问题。每次您在组中达到非零值时,都会创建一个新岛。那么你的工作就是移除那些岛屿 0。代码:

islands = (df['Quantity'] != 0).groupby(level=0).cumsum()
df[islands != 0]

发生的事情的慢动作:

                    Quantity   Quantity != 0?   cumsum
Item1   2016-05-08       0.0           False         0
        2016-05-15       0.0           False         0
        2016-05-22       0.0           False         0
        2016-05-29       456            True         1
        2016-06-05        22            True         2
------------------------------------------------------
Item2   2018-03-08       0.0           False         0
        2018-03-15       300            True         1
        2018-03-21       0.0           False         1
        2018-03-29       0.0           False         1
        2018-03-05       433            True         2

最后,您删除带有cumsum == 0 的行

【讨论】:

  • 嗨,是否可以在特定列上分组而不提及级别?就像假设我想做 groupby(['key']) 并执行操作。我将 level=0 替换为特定列,但出现关键错误。你能提出一个解决方案吗?
【解决方案2】:

另一种选择:将数据帧转换为二维矩阵。用 NaN 替换所有零并进行前向填充。这样一来,一开始的所有 NaN 都保持 NaN,但中间的那些 NaN 就变成了别的东西。找到 NaN 的位置并使用掩码去除相应的零。

mask = df.unstack().replace(0, np.nan).ffill(1).notnull()
new_df = df.unstack()[mask].stack()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-01
    • 2022-01-26
    • 2018-08-03
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 2023-04-02
    相关资源
    最近更新 更多