Измените размер окна при движении

У меня есть кадр данных панд, как это;

>df

leg    speed
  1       10
  1       11
  1       12
  1       13
  1       12
  1       15
  1       19
  1       12
  2       10
  2       10
  2       12
  2       15
  2       19
  2       11
  :        :

Я хочу сделать новую колонку roll_speed где требуется скользящая средняя скорость последних 5 позиций. Но я хочу поставить более подробное условие.

  1. Группа по leg(он не учитывает скорость строк в разных leg,
  2. Я хочу, чтобы скользящее окно было изменено с 1 до 5 максимум в зависимости от доступных строк. Например в leg == 1в первом ряду рассчитывается только один ряд, поэтому скорость прокатки должна быть 10/1 = 10, Для второго ряда доступны только две строки для расчета, скорость прокатки должна быть (10+11)/2 = 10.5,

    leg    speed   roll_speed
      1       10           10    # 10/1
      1       11           10.5  # (10+11)/2
      1       12           11    # (10+11+12)/3
      1       13           11.5  # (10+11+12+13)/4
      1       12           11.6  # (10+11+12+13+12)/5
      1       15           12.6  # (11+12+13+12+15)/5
      1       19           14.2  # (12+13+12+15+19)/5
      1       12           14.2  # (13+12+15+19+12)/5
      2       10           10    # 10/1
      2       10           10    # (10+10)/2
      2       12           10.7  # (10+10+12)/3
      2       15           11.8  # (10+10+12+15)/4
      2       19           13.2  # (10+10+12+15+19)/5
      2       11           13.4  # (10+12+15+19+11)/5
      :        :           
    

Моя попытка:

df['roll_speed'] = df.speed.rolling(5).mean()

Но он просто возвращает NA для строк, где для расчета доступно менее пяти строк. Как мне решить эту проблему? Спасибо за любую помощь!

2 ответа

Решение

Установите параметр min_periods в 1

df['roll_speed'] = df.groupby('leg').speed.rolling(5, min_periods = 1).mean()\
.round(1).reset_index(drop = True)

    leg speed   roll_speed
0   1   10  10.0
1   1   11  10.5
2   1   12  11.0
3   1   13  11.5
4   1   12  11.6
5   1   15  12.6
6   1   19  14.2
7   1   12  14.2
8   2   10  10.0
9   2   10  10.0
10  2   12  10.7
11  2   15  11.8
12  2   19  13.2
13  2   11  13.4

С помощью rolling(5) получит ваши результаты для всех, кроме первых 4 случаев в каждой группе. Мы можем заполнить оставшиеся значения с помощью расширения mean:

(df.groupby('leg').speed.rolling(5)
    .mean().fillna(df.groupby('leg').speed.expanding().mean())
).reset_index(drop=True)

0     10.000000
1     10.500000
2     11.000000
3     11.500000
4     11.600000
5     12.600000
6     14.200000
7     14.200000
8     10.000000
9     10.000000
10    10.666667
11    11.750000
12    13.200000
13    13.400000
Name: speed, dtype: float64
Другие вопросы по тегам