Добавить среднее значение за последний час к каждому образцу фрейма данных pandas

#python #pandas #datetime #time-series #feature-engineering

#python #pandas #дата и время #временные ряды #разработка функций

Вопрос:

Как я уже писал в названии, учитывая фрейм данных pandas с несколькими функциями и с детализацией в минуту, я хочу добавить в качестве новых функций среднее значение за последний 1 час за каждую минуту.

Как я могу это сделать?

Пример:

 import pandas as pd
import datetime
import numpy as np

date_today = datetime.datetime.now()
days = pd.date_range(date_today, date_today   datetime.timedelta(10), freq='T')
data=[]
for i in range(3):
    np.random.seed(seed=i)
    data.append(np.random.randint(1, high=100, size=len(days)))
    
df = pd.DataFrame({'Datetime': days, 'feature1': data[0],'feature2': data[1],'feature3': data[2]})
df = df.set_index('Datetime')
df.index = df.index.map(lambda x: x.replace(second=0,microsecond=0))
 

Итак, теперь я хочу добавить для каждой функции в df добавить среднее значение за последние 60 минут, отбрасывая данные там, где невозможно вычислить это среднее значение.

Любые советы будут оценены

Ответ №1:

Как и в вашем комментарии, вы запрашиваете среднее значение для каждой строки, вычисленной по предыдущим 60 строкам. Это означает переходящее окно.

Следующий цикл сделает это:

 rolling_avg = pd.DataFrame(columns=['f1', 'f2', 'f3'])

for i in range(df.shape[0]):
    if i<60: print(i, df.index[i], str('computation previous 60 minutes not possible'))
    else: rolling_avg.loc[i] = list(df.iloc[i-60:i,[0,1,2]].mean())
 

Наконец, ожидаемый результат:

 rolling_avg

f1  f2  f3
60  48.733333   45.083333   54.433333
61  49.316667   45.150000   54.483333
62  48.600000   46.316667   54.766667
..  ..          ..          ..
 

Это решение довольно медленное, хотя с вашим размером данных выполнимо.
Для больших данных было бы неплохо иметь более быстрое решение.

Комментарии:

1. Привет, спасибо за ваш ответ, но я хочу получить для каждого образца фрейма данных (каждого необработанного) среднее значение за последние 60 минут, отбрасывая первые 59 элементов, где невозможно получить это среднее значение

2. Хорошо, это правильно, я могу исправить и добавить новые функции в старый фрейм данных, что касается скорости, как я могу улучшить?

Ответ №2:

На мой взгляд, я нашел лучшее решение:

Начиная с примера:

 df_new=df.rolling('1h').mean()
df_final=pd.merge(df, df_new, left_index=True, right_index=True)
df_final[60:-1]
 

Комментарии:

1. Есть какой-нибудь способ выбрать последний час из индекса вместо того, чтобы делать 60 наблюдений, записывая что-то вроде .loc[‘1h’] ???

2. Отличное решение!