2016-03-01 11 views
2

С уважением.reindex multiindex pandas dataframe

Я изо всех сил, пытаясь выяснить, как сделать следующую операцию в панд:

У меня есть CSV-файл с временными метками станций, как следующее:

head of the file

Следующая вещь Я это следующие pivot_table с помощью панд:

trips.pivot_table('bike', aggfunc='count', 
         index=['date', 'hour'], 
         columns='station_arrived').fillna(0) 

возвращение что-то вроде этого:

enter image description here

Моя проблема заключается в следующем:

Я хочу, чтобы проиндексировать столбец «час», чтобы иметь индексы от 0 до 23 часов в день, даже если не рассчитывает в этот день.

Ведение REINDEX только с одним индексом легко, но все становится сложнее, когда я пытаюсь это в мультииндексных dataframe

Есть ли способ, чтобы сделать это возможным?

+0

Думаю, вам нужно будет создать пустые строки перед тем, как сделать сводную таблицу. Таким образом, для этого потребуется придумать метод проверки, для каждого индекса, часы которого отсутствуют, затем сгенерируйте строки для этого индекса с нулевыми значениями для отсутствующих часов. Затем создайте шарнир. – Sam

ответ

2
import datetime as dt 
import pandas as pd 
from pandas import Timestamp 

df = pd.DataFrame(
    {'action': ['C', 'C', 'C', 'C', 'C', 'A', 'C'], 
    'bike': [89, 89, 57, 29, 76, 69, 17], 
    'cust_id': [6, 6, 30, 30, 30, 30, 30], 
    'date': [Timestamp('2010-02-02 00:00:00'), 
       Timestamp('2010-02-02 00:00:00'), 
       Timestamp('2010-02-05 00:00:00'), 
       Timestamp('2010-02-05 00:00:00'), 
       Timestamp('2010-02-05 00:00:00'), 
       Timestamp('2010-02-05 00:00:00'), 
       Timestamp('2010-02-05 00:00:00')], 
    'date_arrived': [Timestamp('2010-02-02 14:27:00'), 
         Timestamp('2010-02-02 15:42:00'), 
         Timestamp('2010-02-05 12:06:00'), 
         Timestamp('2010-02-05 12:07:00'), 
         Timestamp('2010-02-05 13:11:00'), 
         Timestamp('2010-02-05 13:14:00'), 
         Timestamp('2010-02-05 13:45:00')], 
    'date_removed': [Timestamp('2010-02-02 13:57:00'), 
         Timestamp('2010-02-02 15:12:00'), 
         Timestamp('2010-02-05 11:36:00'), 
         Timestamp('2010-02-05 11:37:00'), 
         Timestamp('2010-02-05 12:41:00'), 
         Timestamp('2010-02-05 12:44:00'), 
         Timestamp('2010-02-05 13:15:00')], 
    'hour': [14, 15, 12, 12, 13, 13, 13], 
    'station_arrived': [56, 56, 85, 85, 85, 85, 85], 
    'station_removed': [56, 56, 85, 85, 85, 85, 85]}) 

Во-первых, создать почасовой индекс охватывает диапазон дат:

idx = pd.date_range(df.date.min(), df.date.max() + dt.timedelta(days=1), freq='H') 

Теперь вы хотите иметь индекс DATETIME, поэтому установите «date_arrived». Затем используйте groupby с обоими TimeGrouper, чтобы сгруппировать по часам и по телефону station_arrived. count Число ненулевых значений station_arrived. Раскройте результаты, чтобы получить данные в формате сводной таблицы.

Наконец, используйте reindex, чтобы установить индекс на ваш новый почасовой интервал idx и заполнить нулевые значения нулем.

>>> (df 
    .set_index('date_arrived') 
    .groupby([pd.TimeGrouper('H'), 'station_arrived']) 
    .station_arrived 
    .count() 
    .unstack() 
    .reindex(idx) 
    .fillna(0) 
    ) 
station_arrived  56 85 
2010-02-02 00:00:00 0 0 
2010-02-02 01:00:00 0 0 
2010-02-02 02:00:00 0 0 
2010-02-02 03:00:00 0 0 
2010-02-02 04:00:00 0 0 
2010-02-02 05:00:00 0 0 
2010-02-02 06:00:00 0 0 
2010-02-02 07:00:00 0 0 
2010-02-02 08:00:00 0 0 
2010-02-02 09:00:00 0 0 
2010-02-02 10:00:00 0 0 
2010-02-02 11:00:00 0 0 
2010-02-02 12:00:00 0 0 
2010-02-02 13:00:00 0 0 
2010-02-02 14:00:00 1 0 
2010-02-02 15:00:00 1 0 
2010-02-02 16:00:00 0 0 
... 
+0

Очень впечатляющий и причудливый метод! я читал подобный метод по этой ссылке: https://stackoverflow.com/questions/17287933/filling-in-date-gaps-in-multiindex-pandas-dataframe?rq=1 указывая на разборки стопки может быть решением, но ваш просто решил его идеально. Спасибо! И жаль, что вы не сможете повысить свое решение. недостаточно очков для этого. – ghost

Смежные вопросы