#python #pandas #dataframe #date #datetime
Вопрос:
Текущий df:
Date Power 2011-04-18 17:00:01 245.83 2011-04-18 17:00:02 246.02 2011-04-18 17:00:03 245.72 2011-04-18 17:00:04 244.71 2011-04-18 17:00:05 245.93 2011-04-18 17:00:06 243.12 2011-04-18 17:00:07 244.72 2011-04-18 17:00:08 242.44 2011-04-18 17:00:09 246.42 2011-04-18 17:00:10 245.02 ... ...
Я хочу разделить вышеупомянутый фрейм данных на окна размером n=4 (размер является переменным) и перекрытием o=75. Это означает, что 75 процентов окна будут разделены между предыдущим окном и следующим. В этом примере, поскольку 75% n=4 равно 3, я хочу, чтобы окно сдвигалось вправо каждые 1 секунду (3 секунды будут общим перекрытием или 75%). Я хочу создать следующий df.
date start date end power 0 2011-04-18 17:00:01 2011-04-18 17:00:04 [245.83, 246.02, 245.72, 244.71] 1 2011-04-18 17:00:02 2011-04-18 17:00:05 [246.02, 245.72, 244.71, 245.93] 2 2011-04-18 17:00:03 2011-04-18 17:00:06 [245.72, 244.71, 245.93, 243.12] 3 2011-04-18 17:00:04 2011-04-18 17:00:07 [244.71, 245.93, 243.12, 244.72] 4 2011-04-18 17:00:05 2011-04-18 17:00:08 [245.93, 243.12, 244.72, 242.44] 5 2011-04-18 17:00:06 2011-04-18 17:00:09 [243.12, 244.72, 242.44, 246.42] 6 2011-04-18 17:00:07 2011-04-18 17:00:10 [244.72, 242.44, 246.42, 245.02] ... ... ... ...
Есть ли в панд какая-либо функция, которая позволяет вам это делать? Я поискал в документации и не смог найти ничего, что могло бы послужить этой цели.
Я смог использовать следующее, чтобы превратить мой фрейм данных в окна размера n, но мне трудно сделать так, чтобы окна перекрывались.
def make_row(d): return pd.Series({"date_start":d["Date"].min(), "date_end":d["Date"].max(), "power":d["Power"].to_list()}) df.groupby(np.floor(np.linspace(0,len(df)-1,len(df))/n)).apply(make_row).index.astype(int)
Для справки, приведенный выше код приводит к:
date_start date_end power 0 2011-04-18 17:00:01 2011-04-18 17:00:04 [245.83, 246.02, 245.72, 244.71] 1 2011-04-18 17:00:05 2011-04-18 17:00:08 [245.93, 243.12, 244.72, 242.44] ... ... ... ...
Комментарии:
1. будут ли даты всегда увеличиваться на 1 секунду? Это значительно упростило бы проблему
Ответ №1:
Попробуйте, и если это сделает то, что вы ожидаете, я изложу объяснение в правке.
установка
n = 4 o = 50
решение
shift = int(n*(1-o/100)) power_shifted = np.stack([df["Power"].shift(x).iloc[::shift] for x in range(0,-n,-1)]) power_lists = pd.DataFrame(power_shifted).transpose().apply(pd.Series.to_list, axis=1).values result = pd.DataFrame( { "date_start":df["Date"].iloc[::shift], "date_end":df["Date"].shift(-n 1).iloc[::shift], "power":power_lists, } )