Переиндексировать фрейм данных по новому диапазону дат

У меня есть фрейм данных, содержащий ряд наблюдений:

date         colour     orders
2014-10-20   red        7
2014-10-21   red        10
2014-10-20   yellow     3

Я хотел бы переиндексировать фрейм данных и стандартизировать даты.

date         colour     orders
2014-10-20   red        7
2014-10-21   red        10
2014-10-22   red        NaN
2014-10-20   yellow     3
2014-10-21   yellow     NaN
2014-10-22   yellow     NaN

Я хотя бы заказать кадр данных по colour а также date, а затем попробуйте переиндексировать его.

index = pd.date_range('20/10/2014', '22/10/2014')
test_df = df.sort(['colour', 'date'], ascending=(True, True))
ts = test_df.reindex(index)
ts

Но он возвращает новый фрейм данных с правильным индексом, но все NaN ценности.

date         colour     orders
2014-10-20   NaN        NaN
2014-10-21   NaN        NaN
2014-10-22   NaN        NaN

1 ответ

Решение

Начиная с вашего экзаменационного фрейма данных:

In [51]: df
Out[51]:
        date  colour  orders
0 2014-10-20     red       7
1 2014-10-21     red      10
2 2014-10-20  yellow       3

Если вы хотите переиндексировать как "дата", так и "цвет", одна из возможностей - установить оба индекса в качестве индекса (мультииндекса):

In [52]: df = df.set_index(['date', 'colour'])

In [53]: df
Out[53]:
                   orders
date       colour
2014-10-20 red          7
2014-10-21 red         10
2014-10-20 yellow       3

Теперь вы можете переиндексировать этот фрейм данных после того, как вы построили нужный индекс:

In [54]: index = pd.date_range('20/10/2014', '22/10/2014')

In [55]: multi_index = pd.MultiIndex.from_product([index, ['red', 'yellow']])

In [56]: df.reindex(multi_index)
Out[56]:
                   orders
2014-10-20 red          7
           yellow       3
2014-10-21 red         10
           yellow     NaN
2014-10-22 red        NaN
           yellow     NaN

Чтобы получить тот же вывод, что и в вашем примере вывода, индекс должен быть отсортирован на втором уровне (level=1 как это основано на 0):

In [60]: df2 = df.reindex(multi_index)

In [64]: df2.sortlevel(level=1)
Out[64]:
                   orders
2014-10-20 red          7
2014-10-21 red         10
2014-10-22 red        NaN
2014-10-20 yellow       3
2014-10-21 yellow     NaN
2014-10-22 yellow     NaN

Возможный способ автоматически сгенерировать мультииндекс: (с исходным кадром):

pd.MultiIndex.from_product([pd.date_range(df['date'].min(), df['date'].max(), freq='D'), 
                            df['colour'].unique()])

Другой способ будет использовать resample для каждой группы цветов:

In [77]: df = df.set_index('date')

In [78]: df.groupby('colour').resample('D')

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

Другие вопросы по тегам