Python 如果差异为负值,则添加上一行
我有一个包含一些收入值的df,我想将这些值插入到索引中未包含的日期。为此,我要找出行和插值之间的差异: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)。这适用于大多数情况,但也有少数情况下“结账
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