pandas 系列如果差异为负则添加前一行

pandas series add previous row if diff negative

我有一个包含一些收入值的 df,我想将这些值插入到未包含在索引中的日期。为此,我找到了行和插值之间的区别:

rev_diff = df.revenue.diff().fillna(0)
df = df.resample("M").mean()
df["revenue"] = df.revenue.interpolate().diff()

我在一个函数中有这个,它循环了数千个这样的计算(每个计算都创建了这样一个 df)。这适用于大多数情况,但在某些情况下 'checkout till' 会重置,因此差异为负:

            revenue
2015-10-19  203.0
2016-04-03  271.0
2016-06-13  301.0
2016-06-13  0.0
2016-09-27  30.0
2017-03-14  77.0
2017-09-19  128.0
2018-09-19  0.0
2018-03-19  10.0
2019-03-22  287.0
2020-03-20  398.0

上面的代码会给出负插值,所以我想知道是否有一种快速的方法可以在它发生时考虑到这一点,而不会对执行时间造成太大的影响,因为它被调用了数千次。收入 df 的最终结果(在执行插值之前)应该是:

            revenue
2015-10-19  203.0
2016-04-03  271.0
2016-06-13  301.0
2016-09-27  331.0
2017-03-14  378.0
2017-09-19  429.0
2018-03-19  439.0
2019-03-22  716.0   
2020-03-20  827.0

所以基本上如果有 'reset',差异应该添加到上面一行中的值。下面的所有行都会发生这种情况。

我希望这是有道理的。我正在努力寻找一种计算成本不高的方法。

提前致谢。

没有魔法。步骤:

  1. 通过计算收入差异来确定断点。
  2. 填充要为后续数据添加的 revenue 值。
  3. 总结一下。
  4. 删除重复记录。

代码

import pandas as pd
import numpy as np

df.reset_index(inplace=True)

# 1. compute difference
df["rev_diff"] = 0.0
df.loc[1:, "rev_diff"] = df["revenue"].values[1:] - df["revenue"].values[:-1]

# get breakpoint locations
breakpoints = df[df["rev_diff"] < 0].index.values

# 2. accumulate the values to be added
df["rev_add"] = 0.0
for idx in breakpoints:
    add_value = df.at[idx-1, "revenue"]
    df.loc[idx:, "rev_add"] += add_value  # accumulate

# 3. sum up
df["rev_new"] = df["revenue"] + df["rev_add"]

# 4. remove duplicate rows
df_new = df[["index", "rev_new"]].drop_duplicates().set_index("index")
df_new.index.name = None

结果

df_new
Out[85]:
            rev_new
2015-10-19    203.0
2016-04-03    271.0
2016-06-13    301.0
2016-09-27    331.0
2017-03-14    378.0
2017-09-19    429.0
2018-03-19    439.0
2019-03-22    716.0
2020-03-20    827.0