Выбор столбцов из таблицы pandas.HDFStore

Как получить определенные столбцы из pandas HDFStore? Я регулярно работаю с очень большими наборами данных, которые слишком велики для управления в памяти. Я хотел бы прочитать в CSV файле итеративно, добавить каждый кусок в объект HDFStore, а затем работать с подмножествами данных. Я прочитал простой файл csv и загрузил его в HDFStore со следующим кодом:

tmp = pd.HDFStore('test.h5')
chunker = pd.read_csv('cars.csv', iterator=True, chunksize=10, names=['make','model','drop'])
tmp.append('df', pd.concat([chunk for chunk in chunker], ignore_index=True))

И вывод:

In [97]: tmp
Out[97]:
<class 'pandas.io.pytables.HDFStore'>
File path: test.h5
/df     frame_table (typ->appendable,nrows->1930,indexers->[index])

Мой вопрос: как мне получить доступ к определенным столбцам из tmp['df']? В документах упоминается метод select() и некоторые объекты Term. Приведенные примеры применяются к данным Panel; однако, я слишком много начинаю, чтобы распространить его на более простой случай с фреймами данных. Я предполагаю, что мне нужно как-то создать индекс столбцов. Спасибо!

Ответы

Ответ 1

Способ записи таблиц HDFStore, столбцы хранятся по типу как одиночные массивы numpy. Вы всегда возвращаете все столбцы, вы можете фильтровать их, поэтому вы будете возвращены за то, что вы просите. В 0.10.0 вы можете передать Термин, содержащий столбцы.

store.select('df', [ Term('index', '>', Timestamp('20010105')), 
                     Term('columns', '=', ['A','B']) ])

или вы можете повторно проиндексировать впоследствии

df = store.select('df', [ Term('index', '>', Timestamp('20010105') ])
df.reindex(columns = ['A','B'])

axes на самом деле не является решением здесь (то, что вы на самом деле создали, фактически сохраняло транспонированный фрейм). Этот параметр позволяет переупорядочить хранение осей, чтобы обеспечить выравнивание данных по-разному. Для dataframe это действительно не означает многого; для трехмерных или четырехмерных структур выравнивание данных на диске имеет решающее значение для действительно быстрых запросов.

0.10.1 позволит более элегантное решение, а именно столбцы данных, то есть вы можете выбрать определенные столбцы, которые будут представлены как собственные столбцы в хранилище таблиц, поэтому вы действительно можете выбрать именно их. Вот вкус, который придет.

 store.append('df', columns = ['A','B','C'])
 store.select('df', [ 'A > 0', Term('index', '>', Timestamp(2000105)) ])

Еще один способ сделать это - хранить отдельные таблицы в разных узлах файла, тогда вы можете выбрать только то, что вам нужно.

В общем, я рекомендую снова действительно большие таблицы. hayden предлагает решение Panel, которое может быть полезно для вас сейчас, поскольку фактическая структура данных должна отражать то, как вы хотите запросить данные.

Ответ 2

Вы можете хранить фреймворк с индексом столбцов следующим образом:

import pandas as pd
import numpy as np
from pandas.io.pytables import Term

index = pd.date_range('1/1/2000', periods=8)
df = pd.DataFrame( np.random.randn(8,3), index=index, columns=list('ABC'))  

store = pd.HDFStore('mydata.h5')
store.append('df_cols', df, axes='columns')

а затем выберите, как вы могли бы надеяться:

In [8]: store.select('df_cols', [Term('columns', '=', 'A')])
Out[8]: 
2000-01-01    0.347644
2000-01-02    0.477167
2000-01-03    1.419741
2000-01-04    0.641400
2000-01-05   -1.313405
2000-01-06   -0.137357
2000-01-07   -1.208429
2000-01-08   -0.539854

Где:

In [9]: df
Out[9]: 
                   A         B         C
2000-01-01  0.347644  0.895084 -1.457772
2000-01-02  0.477167  0.464013 -1.974695
2000-01-03  1.419741  0.470735 -0.309796
2000-01-04  0.641400  0.838864 -0.112582
2000-01-05 -1.313405 -0.678250 -0.306318
2000-01-06 -0.137357 -0.723145  0.982987
2000-01-07 -1.208429 -0.672240  1.331291
2000-01-08 -0.539854 -0.184864 -1.056217

.

Для меня это не идеальное решение, так как мы можем только индексировать DataFrame одним! Беспокойно документы, кажется, предлагают вам только проиндексировать DataFrame одной вещью, по крайней мере используя axes:

Передайте ключевое слово осей с помощью списка измерений (в настоящее время оно должно быть ровно на 1 меньше, чем общие размеры объекта).

Возможно, я читаю это неправильно, и в этом случае надеюсь, кто-то может доказать мне, что не так!

.

Примечание. Один из способов, с помощью которого я обнаружил, что индекс DataFrame индексирует две вещи (индекс и столбцы), состоит в том, чтобы преобразовать его в Panel, который затем может извлекаться с использованием двух индексов. Однако тогда нам нужно преобразовать в выбранную подпанель в DataFrame каждый раз, когда элементы извлекаются... снова, а не идеально.

Ответ 3

Отныне , U может использовать выражение запроса вместо Term. Например: store.select('df', "index > Timestamp('20000105')")