Seleccionando columnas de la tabla pandas.HDFStore

¿Cómo puedo recuperar columnas específicas de un pandas HDFStore? Regularmente trabajo con conjuntos de datos muy grandes que son demasiado grandes para manipularlos en la memoria. Me gustaría leer iterativamente en un archivo csv, agregar cada fragmento en el objeto HDFStore y luego trabajar con subconjuntos de los datos. He leído un simple archivo csv y lo cargué en un HDFStore con el siguiente código:

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)) 

Y la salida:

 In [97]: tmp Out[97]:  File path: test.h5 /df frame_table (typ->appendable,nrows->1930,indexers->[index]) 

Mi pregunta es ¿cómo tmp['df'] a columnas específicas desde tmp['df'] ? La documentación hace mención de un método select() y algunos objetos Term . Los ejemplos proporcionados se aplican a los datos del Panel; sin embargo, y soy demasiado novato para extenderlo al caso de dataframe más simple. Mi conjetura es que tengo que crear un índice de las columnas de alguna manera. ¡Gracias!

La forma en que HDFStore registra las tablas, las columnas se almacenan por tipo como matrices de un solo número. Siempre recuperas todas las columnas, puedes filtrarlas, por lo que recibirás lo que pidas. En 0.10.0 puede pasar un término que involucra columnas.

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

o puedes reindexar después

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

Los axes no son realmente la solución aquí (lo que realmente creó fue en efecto almacenar un marco transpuesto). Este parámetro le permite reordenar el almacenamiento de los ejes para permitir la alineación de los datos de diferentes maneras. Para un dataframe realmente no significa mucho; para estructuras 3d o 4d, la alineación de datos en disco es crucial para consultas realmente rápidas.

0.10.1 permitirá una solución más elegante, es decir, columnas de datos, es decir, puede elegir que ciertas columnas se representen como columnas propias en el almacén de tablas, por lo que realmente puede seleccionarlas. Aquí hay un sabor de lo que viene.

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

Otra forma de hacerlo es almacenar tablas separadas en diferentes nodos del archivo, luego puede seleccionar solo lo que necesita.

En general, recomiendo de nuevo las tablas muy anchas. Hayden ofrece la solución Panel, que podría ser un beneficio para usted ahora, ya que el arreglo de datos real debe reflejar cómo desea consultar los datos.

Puede almacenar el dataframe con un índice de las columnas de la siguiente manera:

 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') 

y luego seleccione como pueda esperar:

 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 

Dónde:

 In [9]: df Out[9]: ABC 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 

.

Para mí, esta no es una solución ideal, ¡ya que solo podemos indexar el DataFrame por una cosa! Lo preocupante es que los documentos parecen sugerir que solo se puede indexar un DataFrame por una cosa, al menos usando axes :

Pase la palabra clave de ejes con una lista de dimensiones (actualmente debe ser exactamente 1 menos que las dimensiones totales del objeto).

Puede que esté leyendo esto incorrectamente, en cuyo caso, ¡ espero que alguien pueda demostrar que estoy equivocado!

.

Nota: Una forma que he encontrado para indexar un DataFrame por dos cosas (índice y columnas), es convertirlo en un Panel, que luego puede recuperarse usando dos índices. Sin embargo, luego tenemos que convertir al subpanel seleccionado a un DataFrame cada vez que se recuperan los elementos … de nuevo, no es lo ideal.