在 Pandas Groupby 中,在某种条件下找到最远的行

In Pandas Groupby, find farthest row under some condition

让我们采用以下数据框 - 请忽略输入的输出列。输出列是预期的输出。所需日期不同

data = [
    ['Group1', 20211129, 'i', 0, 0],
    ['Group1', 20211202, 'r', 465852069, 3],
    ['Group1', 20211202, 'r', 465852070, 3],
    ['Group1', 20211206, 'i', 0, 0],
    ['Group1', 20211213, 'i', 0, 0],
    ['Group2', 20211129, 'i', 0, 0],
    ['Group2', 20211206, 'i', 0, 0],
    ['Group2', 20211210, 'r', 466486129, 11],
    ['Group2', 20211213, 'i', 0, 0],
    ['Group2', 20211227, 'i', 0, 0],
    ['Group2', 20220103, 'i', 0, 0],
    ['Group2', 20220104, 'r', 467650236, 22],
    ['Group2', 20220105, 'r', 467754363, 23]
]
data = pd.DataFrame(data, columns=['group', 'date', 'type', 'rid', 'output'])
data.date = pd.to_datetime(data.date, yearfirst=True, format='%Y%m%d')
data

对于 type r 的每条记录,我需要在每个 group 中找到向上方向最远的 type i 但不应交叉 type河在上面的示例中,对于第 1 行,第 0 行是最远的 i。对于第 2 行,第 0 行也是最远的 i。对于 Group 的第 7 行,第 5 行是最远的 i。对于第 11 行,第 8 行是最远的 i,因为我们不能跳过 r。对于第 12 行,第 8 行也是最远的 i。最终目标是得到'r'对应的日期字段和最远的'i'.

对应的日期字段的差值

我在 rid 上尝试了 bfill 但没有成功。我认为应该有更简单的方法来实现这一点。

想法是按最后 r 个连续值创建组,并在自定义函数中获取 i 行的最小索引:

#convert to datetimes
data['date'] = pd.to_datetime(data['date'], format='%Y%m%d')

#get Trues for last r consecutive values by chain with shifted value with compare i
g = data['type'].eq('r') & data['type'].shift(-1, fill_value='i').eq('i')

def f(x):
    #get only i rows
    m = x['type'].eq('i')
    #filter date if exist else None and assign to new column
    x['out'] =  next(iter(x.loc[m, 'date']), None)
    return x

#pas groups by column group and groups by last r with cumulative sum
data = data.groupby(['group', g.iloc[::-1].cumsum().iloc[::-1]]).apply(f)
#last get difference with set 0 if not match r
data['out'] = data['date'].sub(data['out']).dt.days.where(data['type'].eq('r'), 0)

print (data)
     group       date type        rid  out
0   Group1 2021-11-29    i          0    0
1   Group1 2021-12-02    r  465852069    3
2   Group1 2021-12-02    r  465852070    3
3   Group1 2021-12-06    i          0    0
4   Group1 2021-12-13    i          0    0
5   Group2 2021-11-29    i          0    0
6   Group2 2021-12-06    i          0    0
7   Group2 2021-12-10    r  466486129   11
8   Group2 2021-12-13    i          0    0
9   Group2 2021-12-27    i          0    0
10  Group2 2022-01-03    i          0    0
11  Group2 2022-01-04    r  467650236   22
12  Group2 2022-01-05    r  467754363   23