熊猫系列如果差异为负则添加上一行

时间:2020-10-17 15:44:18

标签: 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)。这适用于大多数情况,但是在少数情况下,'checkout until'会重置,因此差异为负:

            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

因此,基本上,如果存在“重置”,则应将diff添加到上一行的值中。这将在下面的所有行中发生。

我希望这是有道理的。我正在努力寻找一种方法,而该方法在计算上并不昂贵。

谢谢。

1 个答案:

答案 0 :(得分:1)

没有魔术。步骤:

  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