Использование .asof и MultiIndex в Pandas

#python #pandas

#python #pandas

Вопрос:

Я видел, как этот вопрос задавался несколько раз, но без ответа. Краткая версия:

У меня есть pandas DataFrame с двухуровневым MultiIndex индексом; оба уровня являются целыми числами. Как я могу использовать .asof() это DataFrame ?

Длинная версия:

У меня есть DataFrame данные с некоторыми временными рядами:

 >>> df
                            A
2016-01-01 00:00:00  1.560878
2016-01-01 01:00:00 -1.029380
...                       ...
2016-01-30 20:00:00  0.429422
2016-01-30 21:00:00 -0.182349
2016-01-30 22:00:00 -0.939461
2016-01-30 23:00:00  0.009930
2016-01-31 00:00:00 -0.854283

[721 rows x 1 columns]
  

Затем я создаю еженедельную модель этих данных:

 >>> df['weekday'] = df.index.weekday
>>> df['hour_of_day'] = df.index.hour
>>> weekly_model = df.groupby(['weekday', 'hour_of_day']).mean()
>>> weekly_model
                            A
weekday hour_of_day          
0       0            0.260597
        1            0.333094
...                       ...
        20           0.388932
        21          -0.082020
        22          -0.346888
        23           1.525928
[168 rows x 1 columns]
  

Это то, что дает мне a DataFrame с индексом, описанным выше.

Сейчас я пытаюсь экстраполировать эту модель на годовой временной ряд:

 >>> dates = pd.date_range('2015/1/1', '2015/12/31 23:59', freq='H')
>>> annual_series = weekly
weekly        weekly_model  
>>> annual_series = weekly_model.A.asof((dates.weekday, dates.hour))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/tkcook/azimuth-web/lib/python3.5/site-packages/pandas/core/series.py", line 2657, in asof
    locs = self.index.asof_locs(where, notnull(values))
  File "/home/tkcook/azimuth-web/lib/python3.5/site-packages/pandas/indexes/base.py", line 1553, in asof_locs
    locs = self.values[mask].searchsorted(where.values, side='right')
ValueError: operands could not be broadcast together with shapes (8760,) (2,) 
>>> dates = pd.date_range('2015/1/1', '2015/12/31 23:59', freq='H')
>>> annual_series = weekly_model.A.asof((dates.weekday, dates.hour))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/tkcook/azimuth-web/lib/python3.5/site-packages/pandas/core/series.py", line 2657, in asof
    locs = self.index.asof_locs(where, notnull(values))
  File "/home/tkcook/azimuth-web/lib/python3.5/site-packages/pandas/indexes/base.py", line 1553, in asof_locs
    locs = self.values[mask].searchsorted(where.values, side='right')
ValueError: operands could not be broadcast together with shapes (8760,) (2,) 
  

Что означает эта ошибка и каков наилучший способ сделать это?

Лучшее, что я придумал до сих пор, это:

 >>> annual_series = weekly_model.A.loc[list(zip(dates.weekday, dates.hour))]
  

Это работает, но сначала это означает превращение zip итератора в список, что не совсем удобно для памяти. Есть ли способ избежать этого?

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

1. Эй, Том, asof нуждается в вводе даты. когда вы используете даты. день недели или даты. в час он возвращает целое число

Ответ №1:

Я прочитал ваш пост несколько раз, и я думаю, что наконец-то понял, чего вы пытаетесь достичь.

попробуйте это:

 df['weekday'] = df.index.weekday
df['hour_of_day'] = df.index.hour
weekly_model = df.groupby(['weekday', 'hour_of_day']).mean()
dates = pd.date_range('2015/1/1', '2015/12/31 23:59', freq='H')
  

затем используйте слияние следующим образом:

 annual_series = pd.merge(df.reset_index(), weekly_model.reset_index(), on=['weekday', 'hour_of_day']).set_index('date')
  

теперь вы можете использовать asof, поскольку у вас есть даты в качестве индекса

 annual_series.asof(dates)
  

это то, что вы искали?