2014-09-05 3 views
2

У меня есть вопрос относительно того, как фильтровать результаты в функции pd.read_hdf. Итак, вот настройка, у меня есть pandas dataframe (с индексом np.datetime64), который я вложил в файл hdf5. Здесь нет ничего интересного, поэтому не нужно использовать иерархию или что-то еще (возможно, я мог бы включить ее?). Вот пример:Pandas read_hdf запрос по дате и времени

       Foo   Bar 
TIME           
2014-07-14 12:02:00   0   0 
2014-07-14 12:03:00   0   0 
2014-07-14 12:04:00   0   0 
2014-07-14 12:05:00   0   0 
2014-07-14 12:06:00   0   0 
2014-07-15 12:02:00   0   0 
2014-07-15 12:03:00   0   0 
2014-07-15 12:04:00   0   0 
2014-07-15 12:05:00   0   0 
2014-07-15 12:06:00   0   0 
2014-07-16 12:02:00   0   0 
2014-07-16 12:03:00   0   0 
2014-07-16 12:04:00   0   0 
2014-07-16 12:05:00   0   0 
2014-07-16 12:06:00   0   0 

Теперь я храню это в .h5 с помощью следующей команды:

store = pd.HDFStore('qux.h5') 
#generate df 
store.append('data', df) 
store.close() 

Далее, у меня будет еще один процесс, который получает доступ к этой информации, и я хотел бы взять дату/временных фрагментов этих данных. Поэтому предположим, что мне нужны даты между 2014-07-14 и 2014-07-15, и только в промежутках между 12:02:00 и 12:04:00. В настоящее время я использую следующую команду, чтобы получить это:

pd.read_hdf('qux.h5', 'data', where='index >= 20140714 and index <= 20140715').between_time(start_time=datetime.time(12,2), end_time=datetime.time(12,4)) 

Насколько я знаю, кто-то пожалуйста, поправьте меня, если я ошибаюсь здесь, но весь исходный набор данных не считывается в память, если я использую ' где'. Итак, другими словами:

это:

pd.read_hdf('qux.h5', 'data', where='index >= 20140714 and index <= 20140715') 

не то же самое, как это:

pd.read_hdf('qux.h5', 'data')['20140714':'20140715'] 

Хотя конечный результат в точности то же самое, что делается в фоновом режиме нет. Поэтому мой вопрос: есть ли способ включить этот фильтр временного интервала (т. Е. .between_time()) в оператор where? Или, если есть другой способ, я должен создать свой файл hdf5? Может быть, хранить столик на каждый день?

Спасибо!

EDIT:

Что касается использования иерархии, я знаю, что структура должна быть в значительной степени зависит от того, как я буду использовать данные. Однако, если предположить, что я определяю таблицу за дату (например, «df/date_20140714», «df/date_20140715», ...). Опять же, я могу ошибаться здесь, но используя свой пример запроса времени/диапазона времени; Вероятно, я понесу штраф за исполнение, поскольку мне нужно будет прочитать каждую таблицу и объединить их, если я хочу получить консолидированный вывод?

ответ

7

Смотрите пример выбора с использованием where mask

Вот пример

In [50]: pd.set_option('max_rows',10) 

In [51]: df = DataFrame(np.random.randn(1000,2),index=date_range('20130101',periods=1000,freq='H')) 

In [52]: df 
Out[52]: 
          0   1 
2013-01-01 00:00:00 -0.467844 1.038375 
2013-01-01 01:00:00 0.057419 0.914379 
2013-01-01 02:00:00 -1.378131 0.187081 
2013-01-01 03:00:00 0.398765 -0.122692 
2013-01-01 04:00:00 0.847332 0.967856 
...      ...  ... 
2013-02-11 11:00:00 0.554420 0.777484 
2013-02-11 12:00:00 -0.558041 1.833465 
2013-02-11 13:00:00 -0.786312 0.501893 
2013-02-11 14:00:00 -0.280538 0.680498 
2013-02-11 15:00:00 1.533521 -1.992070 

[1000 rows x 2 columns] 

In [53]: store = pd.HDFStore('test.h5',mode='w') 

In [54]: store.append('df',df) 

In [55]: c = store.select_column('df','index') 

In [56]: where = pd.DatetimeIndex(c).indexer_between_time('12:30','4:00') 

In [57]: store.select('df',where=where) 
Out[57]: 
          0   1 
2013-01-01 00:00:00 -0.467844 1.038375 
2013-01-01 01:00:00 0.057419 0.914379 
2013-01-01 02:00:00 -1.378131 0.187081 
2013-01-01 03:00:00 0.398765 -0.122692 
2013-01-01 04:00:00 0.847332 0.967856 
...      ...  ... 
2013-02-11 03:00:00 0.902023 1.416775 
2013-02-11 04:00:00 -1.455099 -0.766558 
2013-02-11 13:00:00 -0.786312 0.501893 
2013-02-11 14:00:00 -0.280538 0.680498 
2013-02-11 15:00:00 1.533521 -1.992070 

[664 rows x 2 columns] 

In [58]: store.close() 

Пара точек отметить. Это читается во всем индексе для начала. Обычно это не бремя. Если это вы можете просто chunk прочитать его (обеспечить start/stop, хотя его немного руководство для этого ATM). Current select_column Я тоже не могу принять запрос.

Возможно, вы можете переименовать дни (и делать индивидуальные запросы), если у вас есть гигантское количество данных (десятки миллионов строк, которые являются широкими), что может быть более эффективным.

Данные рекомбинации относительно дешевы (через concat), поэтому не бойтесь подзапроса (хотя это слишком сильно может перетащить и перфоманс).

+0

Можно ли объединить его с регулярным предложением 'where' строки, например, например. если я хочу также фильтровать '' sym = 'RIC' "'? –