Продолжить столбец со средним значением предыдущих значений - PullRequest
0 голосов
/ 29 мая 2020

У меня есть несколько столбцов, проиндексированных по дате и времени, и мне нужно спроецировать прогноз для некоторых столбцов на основе последних n (скажем, в данном случае 4) дней.

          A  B  C
31-12-201917 19 49
1-1-2020  4  9  2
2-1-2020  2  23 3
3-1-2020  8  23 7
4-1-2020  6  21 4
5-1-2020  5
6-1-2020  5
7-1-2020  5
8-1-2020  5
9-1-2020  5
10-1-2020 5 
11-1-2020 5

Таким образом, желаемый результат будет иметь среднее значение за последние 4 дня как соответствующее значение для этого столбца для каждой из будущих дат (как показано в столбце A). Обратите внимание, что это должно занять только последние 4 дня, а не все даты во фрейме данных.

Я пробовал различные функции прокрутки ave, но все, кажется, требуют нового столбца!

Может ли кто-нибудь помочь?

Ответы [ 3 ]

1 голос
/ 29 мая 2020

Вы пробовали (при условии, что df - это pandas.DataFrame):

days_logged = 5
rolling_days = 4
cols = ['B', 'C']

for col in cols:
    for i in range(days_logged, len(df.index)):
        df[col].iloc[i] =  df[col].iloc[i - rolling_days: i].mean()
1 голос
/ 29 мая 2020

Это не лучшее решение, но оно очень расширяемое. df.update - ваш спаситель в таких ситуациях.

import pandas as pd

df = pd.DataFrame([[17, 19, 49],
                   [4, 9, 2],
                   [2, 23, 3],
                   [8, 23, 7],
                   [6, 21, 24],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""]], columns=list("ABC"))

df.index = pd.date_range(start="12-31-2019", end="01-11-2020", freq="D")

def forecast(df):
    last_day = df.iloc[-1]
    new_day = last_day.name + pd.Timedelta(days=1)
    new_data = df.loc[last_day.name - pd.Timedelta(days=3):last_day.name, :].mean()
    new_data.name = new_day
    return new_data

num_predict_days = 7
columns_to_predict = ['B', 'C']

available_data = df.shape[0] - num_predict_days
df_to_predict = df.iloc[:available_data, :].loc[:, columns_to_predict]

for i in range(num_predict_days):
    df_to_predict = df_to_predict.append(forecast(df_to_predict))

df.update(df_to_predict)
1 голос
/ 29 мая 2020

Итак, повторяя значения 5 в столбце, я предполагаю, что это так же просто, как заполнить NaN постоянным значением, полученным в результате некоторого усреднения, верно?

Так как насчет:

for c in df.columns:
    df[c].fillna(
        df[df[c].notna()].tail(4)[c].mean(),
        inplace=True
    )
  • .fillna() просто заполняет значения NaN
  • df[df[c].notna()].tail(4) дает вам последние 4 дня, отличные от нанометров. не стесняйтесь изменять значение .tail()
  • [c].mean() усредняет значения для столбца c
...