Python 如果差异为负值,则添加上一行

Python 如果差异为负值,则添加上一行,python,pandas,dataframe,data-wrangling,Python,Pandas,Dataframe,Data Wrangling,我有一个包含一些收入值的df,我想将这些值插入到索引中未包含的日期。为此,我要找出行和插值之间的差异: rev_diff = df.revenue.diff().fillna(0) df = df.resample("M").mean() df["revenue"] = df.revenue.interpolate().diff() 我把它放在一个函数中,它被循环了数千次这样的计算(每一次都创建了这样一个df)。这适用于大多数情况,但也有少数情况下“结账

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

rev_diff = df.revenue.diff().fillna(0)
df = df.resample("M").mean()
df["revenue"] = df.revenue.interpolate().diff()
我把它放在一个函数中,它被循环了数千次这样的计算(每一次都创建了这样一个df)。这适用于大多数情况,但也有少数情况下“结账日”重置,因此差异为负值:

            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
因此,基本上,如果存在“重置”,则应将差异添加到上一行的值中。下面的所有行都会发生这种情况

我希望这是有道理的。我正在努力寻找一种在计算上不花费太多的方法

提前谢谢。

没有魔法。步骤:

  • 通过计算收入差异来确定断点
  • 填充要为后续数据添加的
    收入
  • 总结一下
  • 删除重复记录
  • 代码
    为什么2017-03-14的收入不是378?我不明白为什么在77.0>30.0(以前的收入)时会发生重置。我认为,当存在较大的数据差距或收入变化时,使用运行差异识别重置对于生产使用来说太不可靠了。例如:
    2016-04-01=50.0
    ,然后是
    2017-03-25=70.0
    。中间有重置吗?从业务逻辑来看,可能存在这种情况,但从数据来看,您无法判断。您好@BillHuang,您在第二条评论中是对的,我没有添加几行指示收入重置的内容。假设它们发生在记录以前收入的同一天。我编辑了第一个数据帧。谢谢你指出这一点。你仍然没有解释第一条评论
    2017-03-14=408
    与您在标题中所述的规则不匹配。ooops,您是对的。我很快创建了df,没有注意到我没有添加差异。
    2017-03-14
    收入将是378,然后是429等等。谢谢@BillHuang!
    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