Существует ли способ сделать окно в df.rolling динамическим в зависимости от строки, для которой выполняется расчет?

Вопрос или проблема

У меня есть набор данных о ценах акций, и я хочу добавить столбец с минимальными значениями за 52 недели для каждого дня. Однако для строк, в которых нет 365 дней выше, я просто хочу, чтобы в этом столбце было скользящее минимальное значение, используя любое количество строк, которые находятся выше.

Я пробовал такой код, но это, очевидно, не работает, потому что он создает столбец дважды.

for row in data.iterrows():
  if row[0] < (data.index[0] + timedelta(days = 365)):
    data['52wkLow'] = data['Low']['GME'].rolling((row[0]-data.index[0]).days).min()
  elif row[0] > (data.index[0] + timedelta(days = 365)):
    data['52wkLow'] = data['Low']['GME'].rolling(365).min()

Вот пример данных, по которым я хотел бы получить скользящее минимум:

Date
2021-01-04     17.250000
2021-01-05     17.370001
2021-01-06     18.360001
2021-01-07     18.080000
2021-01-08     17.690001
2021-01-11     19.940001
2021-01-12     19.950001
2021-01-13     31.400000
2021-01-14     39.910000
2021-01-15     35.500000
2021-01-19     39.360001
2021-01-20     39.119999
2021-01-21     43.029999
2021-01-22     65.010002
2021-01-25     76.790001
2021-01-26    147.979996
2021-01-27    347.510010
2021-01-28    193.600006
2021-01-29    325.000000
2021-02-01    225.000000
2021-02-02     90.000000
2021-02-03     92.410004
2021-02-04     53.500000
2021-02-05     63.770000
2021-02-08     60.000000
2021-02-09     50.310001
2021-02-10     51.200001
2021-02-11     51.099998
2021-02-12     52.400002
2021-02-16     49.509998
2021-02-17     45.939999
2021-02-18     40.689999
2021-02-19     40.590000
2021-02-22     46.000000
2021-02-23     44.970001
2021-02-24     91.709999
2021-02-25    108.730003
2021-02-26    101.739998
2021-03-01    120.400002
2021-03-02    118.180000
2021-03-03    124.180000
2021-03-04    132.350006
2021-03-05    137.740005
2021-03-08    194.500000
2021-03-09    246.899994
2021-03-10    265.000000
2021-03-11    260.000000
2021-03-12    264.500000
2021-03-15    220.139999
2021-03-16    208.169998
2021-03-17    209.809998
Name: GME, dtype: float64

Просто используйте .rolling(365, min_periods=1), цикл for не нужен

data['52wkLow'] = data['Low']['GME'].rolling(365,min_periods=1).min()

Ответ или решение

Для вашей задачи найти минимальное значение за последние 52 недели, динамически в зависимости от доступных данных, можно воспользоваться методом rolling с параметром min_periods. Этот параметр позволяет указать минимальное количество ненулевых записей, чтобы вычислить скользящее значение. В вашем случае вы хотите использовать 365 дней, но при этом учитывать данные и за меньший период, если доступно меньше строк.

Вот как это можно сделать без циклов.

Пример кода

import pandas as pd

# Пример данных
data = {
    'Date': [
        '2021-01-04', '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08',
        '2021-01-11', '2021-01-12', '2021-01-13', '2021-01-14', '2021-01-15',
        '2021-01-19', '2021-01-20', '2021-01-21', '2021-01-22', '2021-01-25',
        '2021-01-26', '2021-01-27', '2021-01-28', '2021-01-29', '2021-02-01',
        '2021-02-02', '2021-02-03', '2021-02-04', '2021-02-05', '2021-02-08',
        '2021-02-09', '2021-02-10', '2021-02-11', '2021-02-12', '2021-02-16',
        '2021-02-17', '2021-02-18', '2021-02-19', '2021-02-22', '2021-02-23',
        '2021-02-24', '2021-02-25', '2021-02-26', '2021-03-01', '2021-03-02',
        '2021-03-03', '2021-03-04', '2021-03-05', '2021-03-08', '2021-03-09',
        '2021-03-10', '2021-03-11', '2021-03-12', '2021-03-15', '2021-03-16',
        '2021-03-17'
    ],
    'Low': [
        17.25, 17.37, 18.36, 18.08, 17.69,
        19.94, 19.95, 31.40, 39.91, 35.50,
        39.36, 39.12, 43.03, 65.01, 76.79,
        147.97, 347.51, 193.60, 325.00, 225.00,
        90.00, 92.41, 53.50, 63.77, 60.00,
        50.31, 51.20, 51.10, 52.40, 49.51,
        45.94, 40.69, 40.59, 46.00, 44.97,
        91.71, 108.73, 101.74, 120.40, 118.18,
        124.18, 132.35, 137.74, 194.50, 246.90,
        265.00, 260.00, 264.50, 220.14, 208.17,
        209.81
    ]
}

# Преобразование данных в DataFrame
df = pd.DataFrame(data)
df['Date'] = pd.to_datetime(df['Date'])
df.set_index('Date', inplace=True)

# Вычисление 52-недельного минимума
df['52wkLow'] = df['Low'].rolling(window=365, min_periods=1).min()

# Вывод результата
print(df)

Объяснение

  1. Создание DataFrame: Мы создаем DataFrame из ваших данных, где ‘Date’ указывается как индекс.

  2. Метод .rolling(): Используется метод rolling(window=365, min_periods=1), который будет учитывать 365 дней для расчета минимума, но также будет возвращать значение даже для первых записей, где доступных данных меньше (например, для первых 10 дней вы получите минимум из этих 10).

  3. Вычисление минимума: Метод min() вычисляет минимальное значение за указанный период.

Таким образом, ваш новый столбец ’52wkLow’ будет содержать правильные минимальные значения, динамически подстраиваясь под имеющееся количество данных.

Оцените материал
Добавить комментарий

Капча загружается...