在 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
让我们采用以下数据框 - 请忽略输入的输出列。输出列是预期的输出。所需日期不同
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