Если я правильно понимаю ваш вопрос, вам нужно динамическое «скользящее окно», по которому можно рассчитать минимальное значение. Предполагая, что ваш индекс является индексом по умолчанию, то есть он отсортирован в порядке возрастания, вы можете попробовать следующий подход:
import pandas as pd
import numpy as np
from bisect import bisect_left
df = pd.DataFrame({'open': [1, 2, 3, 4, 5],
'high': [5, 6, 6, 5, 7],
'low': [1, 3, 2, 4, 4],
'close': [3, 5, 3, 5, 6]})
При этом используются те же данные выборки, что и для mommermi, но с низким значением на третий день, измененным на 2, поскольку третий день также должен быть включен в "скользящее окно".
df['day'] = np.where(df['close'] > df['open'], 'bull', None)
Мы вычисляем столбец day
, используя векторизованную операцию numpy, которая должна быть немного быстрее.
bull_index_array = df.loc[df['day'] == 'bull'].index
Мы храним значения индекса строк (дней), которые мы пометили как быки.
def find_index(a, x):
i = bisect_left(a, x)
return a[i-1]
Bisect из базовой библиотеки позволит нам эффективно найти индекс предыдущего бычьего дня. Для этого требуется, чтобы индекс был отсортирован по умолчанию.
def min_value(x):
cur_index = x.name
prev_bull_index = find_index(bull_index_array, cur_index)
return df.loc[prev_bull_index:cur_index, 'low'].min()
Далее мы определяем функцию, которая будет создавать наше «динамическое» скользящее окно, разрезая исходный кадр данных по предыдущему и текущему индексу.
df['min'] = df.apply(min_value, axis=1)
Наконец, мы применяем функцию min_value построчно к кадру данных, получая это:
open high low close day min
0 1 5 1 3 bull NaN
1 2 6 3 5 bull 1.0
2 3 6 2 3 None 2.0
3 4 5 4 5 bull 2.0
4 5 7 4 6 bull 4.0