Прежде всего, мы вычисляем логический столбец, чтобы узнать, был ли он пополнен, как вы делаете.
df['replenished'] = df['R'] > 0
Мы также вычисляем приращение в деньгах, которое будет полезно для выполнения остальныхопераций.
df['increment'] = df['R'] - df['T']
Мы также создаем столбец, который будет иметь желаемые значения в свое время, я назвал его резерв .Для начала, мы делаем накопленную сумму приращений, которая является желаемым значением от первого дня пополнения до следующего.
df['reserve'] = df['increment'].cumsum()
Теперь мы собираемся создать вспомогательный псевдоним нашего фрейма данных,который будет полезен для выполнения операций без потери исходных данных.Помните, что эта переменная не является копией, она указывает на те же данные, что и оригинал: изменение df_aux
изменит исходную переменную df
.
df_aux = df
Затем мы можем перейти к циклуэто решит проблему.
while not df_aux.empty:
df_aux = df_aux.loc[df_aux.loc[df_aux['replenished']].index[0]:]
k = df_aux.at[df_aux.index[0], 'reserve']
l = df_aux.at[df_aux.index[0], 'increment']
df_aux['reserve'] = df_aux['reserve'] - k + l
if len(df_aux) > 1:
df_aux = df_aux.loc[df_aux.index[1]:]
else:
break
Сначала мы берем все данные, начиная со следующего дня пополнения.С этого дня до следующего дня пополнения накопленная сумма даст нам желаемый результат, если начальное значение будет равно инкременту, поэтому мы изменим сумму так, чтобы первое значение соответствовало этому условию.
Затем,если это был последний ряд данных, наша работа завершена, и мы выходим из цикла.Если это не так, то мы отбрасываем только что рассчитанный день пополнения и переходим к следующим дням.
После всех этих операций результат (df
) будет таким:
Date R T increment replenished reserve
0 2011-05-03 100 50 50 True 50
1 2011-05-04 0 30 -30 False 20
2 2011-05-05 0 10 -10 False 10
3 2011-05-06 200 110 90 True 90
4 2011-05-07 0 30 -30 False 60
5 2011-05-08 60 20 40 True 40
У меня нет опыта в расчете времени исчисления, поэтому я не уверен, что это решение быстрее, чем цикл по всем строкам.