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',差异应该添加到上面一行中的值。下面的所有行都会发生这种情况。
我希望这是有道理的。我正在努力寻找一种计算成本不高的方法。
提前致谢。
没有魔法。步骤:
- 通过计算收入差异来确定断点。
- 填充要为后续数据添加的
revenue
值。
- 总结一下。
- 删除重复记录。
代码
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
我有一个包含一些收入值的 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',差异应该添加到上面一行中的值。下面的所有行都会发生这种情况。
我希望这是有道理的。我正在努力寻找一种计算成本不高的方法。
提前致谢。
没有魔法。步骤:
- 通过计算收入差异来确定断点。
- 填充要为后续数据添加的
revenue
值。 - 总结一下。
- 删除重复记录。
代码
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