通过组ID获取最后n行的值之和

时间:2018-10-29 21:06:49

标签: python database pandas dataframe data-manipulation

我只想知道如何从每行中获取基于id的最后5个值的总和。

df:

id       values
-----------------
a        5
a        10
a        10
b        2
c        2
d        2
a        5
a        10
a        20
a        10
a        15
a        20

预期df:

id       values       sum(x.tail(5))
-------------------------------------
a        5            NaN
a        10           NaN
a        10           NaN
b        2            NaN
c        2            NaN
d        2            NaN
a        5            NaN
a        10           NaN
a        20           40
a        10           55
a        15           55
a        20           60

为简单起见,我试图从ID为 a 的每行中查找最后第5行的值之和。

我尝试使用代码df.apply(lambda x: x.tail(5)),但这只显示了整个df的最后5行。我想从每一行中获取最后n行的总和。基本上,它类似于时间序列数据的 rolling_sum

2 个答案:

答案 0 :(得分:1)

您可以像下面这样计算最后5个和:

df["rolling As"] = df[df['id'] == 'a'].rolling(window=5).sum()["values"]

(这包括当前行作为5.的不确定行之一)

id  values  rolling As
0   a   5   NaN
1   a   10  NaN
2   a   10  NaN
3   b   2   NaN
4   c   2   NaN
5   d   5   NaN
6   a   10  NaN
7   a   20  55.0
8   a   10  60.0
9   a   10  60.0
10  a   15  65.0
11  a   20  75.0

如果您不希望包含它。你可以换

df["rolling"] = df[df['id'] == 'a'].rolling(window=5).sum()["values"].shift()

给出:

id  values  rolling
0   a   5   NaN
1   a   10  NaN
2   a   10  NaN
3   b   2   NaN
4   c   2   NaN
5   d   5   NaN
6   a   10  NaN
7   a   20  NaN
8   a   10  55.0
9   a   10  60.0
10  a   15  60.0
11  a   20  65.0

答案 1 :(得分:1)

尝试使用groupbytransformrolling

df['sum(x.tail(5))'] = df.groupby('id')['values']\
                         .transform(lambda x: x.rolling(5, min_periods=5).sum().shift())

输出:

   id values  sum(x.tail(5))
1   a      5             NaN
2   a     10             NaN
3   a     10             NaN
4   b      2             NaN
5   c      2             NaN
6   d      2             NaN
7   a      5             NaN
8   a     10             NaN
9   a     20            40.0
10  a     10            55.0
11  a     15            55.0
12  a     20            60.0