pandas - 从组中取N个最后一个值

时间:2018-01-21 12:50:51

标签: python algorithm pandas group-by

我的数据框看起来像那样(日期的格式为:dd/mm/yyyy):

      Param1 Param2    date       value
1       a      b    30/10/2007      5
2       a      b    31/10/2007      8
3       a      b    01/11/2007      9
4       a      b    01/12/2007      3
5       a      b    02/12/2007      2
6       a      b    01/03/2008      11
7       b      c    05/10/2008      7
8       b      c    06/10/2008      13
9       b      c    07/10/2008      19
10      b      c    08/11/2008      22
11      b      c    09/11/2008      35
12      b      c    08/12/2008      5

我需要做的是按Param1Param2进行分组,并为最后3个值创建N(在我的情况下为3)其他列,至少为30离当前行几天。 所以输出看起来应该是这样的:

      Param1 Param2    date       value  prev_1 prev_2 prev_3
1       a      b    30/10/2007      5     None   None   None
2       a      b    31/10/2007      8     None   None   None
3       a      b    01/11/2007      9     None   None   None
4       a      b    01/12/2007      3      9      8      5
5       a      b    02/12/2007      2      9      8      5
6       a      b    01/03/2008      11     2      3      9
7       b      c    05/10/2008      7     None   None   None
8       b      c    06/10/2008      13    None   None   None
9       b      c    07/10/2008      19    None   None   None
10      b      c    08/11/2008      22      19    13     7
11      b      c    09/11/2008      35      19    13     7 
12      b      c    08/12/2008      5       22    19    13 

我尝试过使用set_indexstack和相关功能,但我无法弄明白(没有丑陋的for)。

任何帮助将不胜感激!

编辑:虽然它类似于这个问题:question

它并不完全相同,因为你不能做一个简单的shift,因为你需要检查至少30天的差距。

1 个答案:

答案 0 :(得分:1)

这是我的建议:

data.date = pd.to_datetime(data.date, dayfirst=True)
data['ind'] = data.index

def func(a):
    aa = data[(data.ind<a.ind)\
        &(data.Param1==a.Param1)&(data.Param2==a.Param2)&(data.date<=(a.date-np.timedelta64(30, 'D')))]
    aaa = [np.nan]*3+list(aa.value.values)
    aaaa = pd.Series(aaa[::-1][:3], index=['prev_1', 'prev_2', 'prev_3'])
    return pd.concat([a, aaaa])

data.apply(func, 1).drop('ind',1)

enter image description here