Хорошо, наконец-то мне удалось решить мою проблему.
Вот шаги:
Если строка первого бегуна не начинается с 0, вам нужно добавить фиктивную строку с cum_distance = 0 для правильного расчета. Вы можете удалить его потом:
#unique runners ids
idx = np.unique(df.runner.values, return_index=1)[1]
for i in idx:
if df.loc[i,'cum_distance']!=0:
df.loc[df.shape[0]]=[df.loc[i,'runner'],pd.to_datetime('1900-01-01'),0,0] #adding a row
df.sort_values(['runner', 'date'], ascending=[True, True],inplace=True)
df = df.reset_index(drop=True)#reset index
Рассчитать расстояние diff для каждой строки (первый ряд NaN заполнен cum_distance):
df['runner_dist_since_reset'] = df.groupby('runner')['cum_distance'].diff().fillna(df['cum_distance'])
Выход:
runner date cum_distance reset_event runner_dist_since_reset
0 1 2017-04-01 100 1 100.0
1 1 2018-04-20 125 0 25.0
2 1 2018-05-25 130 1 5.0
3 2 2015-04-05 10 1 10.0
4 2 2015-10-20 20 1 10.0
5 2 2016-11-29 50 0 30.0
Использовать тег reset_event в качестве сброса часов:
df.loc[:, 'runner_dist_since_reset'] = df.groupby(['runner', df['reset_event'].shift().cumsum()])['runner_dist_since_reset'].cumsum().fillna(df['cum_distance'])
Выход:
runner date cum_distance reset_event runner_dist_since_reset
0 1 2017-04-01 100 1 100.0
1 1 2018-04-20 125 0 25.0
2 1 2018-05-25 130 1 30.0
3 2 2015-04-05 10 1 10.0
4 2 2015-10-20 20 1 10.0
5 2 2016-11-29 50 0 30.0
Yatu , спасибо вам за то, что показали мне функцию 'cumsum'.