Cómo resolver problemas Excepción de HDFStore: no se puede encontrar el tipo de átomo correcto

Estoy buscando una guía general sobre qué tipos de escenarios de datos pueden causar esta excepción. He intentado masajear mis datos de varias maneras en vano.

He buscado en Google esta excepción desde hace días, he pasado por varias discusiones de grupos de Google y no HDFStore Exception: cannot find the correct atom type una solución para la depuración HDFStore Exception: cannot find the correct atom type . Estoy leyendo en un archivo csv simple de tipos de datos mixtos:

 Int64Index: 401125 entries, 0 to 401124 Data columns: SalesID 401125 non-null values SalePrice 401125 non-null values MachineID 401125 non-null values ModelID 401125 non-null values datasource 401125 non-null values auctioneerID 380989 non-null values YearMade 401125 non-null values MachineHoursCurrentMeter 142765 non-null values UsageBand 401125 non-null values saledate 401125 non-null values fiModelDesc 401125 non-null values Enclosure_Type 401125 non-null values ................................................... Stick_Length 401125 non-null values Thumb 401125 non-null values Pattern_Changer 401125 non-null values Grouser_Type 401125 non-null values Backhoe_Mounting 401125 non-null values Blade_Type 401125 non-null values Travel_Controls 401125 non-null values Differential_Type 401125 non-null values Steering_Controls 401125 non-null values dtypes: float64(2), int64(6), object(45) 

Código para almacenar el dataframe:

 In [30]: store = pd.HDFStore('test0.h5','w') In [31]: for chunk in pd.read_csv('Train.csv', chunksize=10000): ....: store.append('df', chunk, index=False) 

Tenga en cuenta que si uso store.put en un fotogtwig de datos importado en una sola toma, puedo almacenarlo con éxito, aunque lentamente (creo que esto se debe al declive de los tipos de objetos, incluso aunque el objeto sea solo datos de cadena).

¿Hay consideraciones de valor de NaN que podrían estar lanzando esta excepción?

Excepción:

 Exception: cannot find the correct atom type -> [dtype->object,items->Index([Usa geBand, saledate, fiModelDesc, fiBaseModel, fiSecondaryDesc, fiModelSeries, fiMo delDescriptor, ProductSize, fiProductClassDesc, state, ProductGroup, ProductGrou pDesc, Drive_System, Enclosure, Forks, Pad_Type, Ride_Control, Stick, Transmissi on, Turbocharged, Blade_Extension, Blade_Width, Enclosure_Type, Engine_Horsepowe r, Hydraulics, Pushblock, Ripper, Scarifier, Tip_Control, Tire_Size, Coupler, Co upler_System, Grouser_Tracks, Hydraulics_Flow, Track_Type, Undercarriage_Pad_Wid th, Stick_Length, Thumb, Pattern_Changer, Grouser_Type, Backhoe_Mounting, Blade_ Type, Travel_Controls, Differential_Type, Steering_Controls], dtype=object)] lis t index out of range 

ACTUALIZACIÓN 1

La sugerencia de Jeff sobre las listas almacenadas en el dataframe me llevó a investigar comas incrustadas. pandas.read_csv está analizando correctamente el archivo y, de hecho, hay algunas comas incrustadas entre comillas dobles. Entonces, estos campos no son listas de python per se, pero sí tienen comas en el texto. Aquí hay unos ejemplos:

 3 Hydraulic Excavator, Track - 12.0 to 14.0 Metric Tons 6 Hydraulic Excavator, Track - 21.0 to 24.0 Metric Tons 8 Hydraulic Excavator, Track - 3.0 to 4.0 Metric Tons 11 Track Type Tractor, Dozer - 20.0 to 75.0 Horsepower 12 Hydraulic Excavator, Track - 19.0 to 21.0 Metric Tons 

Sin embargo, cuando elimino esta columna de los fragmentos pd.read_csv y la agrego a mi HDFStore, todavía obtengo la misma excepción. Cuando trato de adjuntar cada columna individualmente, obtengo la siguiente nueva excepción:

 In [6]: for chunk in pd.read_csv('Train.csv', header=0, chunksize=50000): ...: for col in chunk.columns: ...: store.append(col, chunk[col], data_columns=True) Exception: cannot properly create the storer for: [_TABLE_MAP] [group->/SalesID (Group) '',value->,table->True,append->True,k wargs->{'data_columns': True}] 

Voy a seguir para solucionar problemas. Aquí hay un enlace a varios cientos de registros:

https://docs.google.com/spreadsheet/ccc?key=0AutqBaUiJLbPdHFvaWNEMk5hZ1NTNlVyUVduYTZTeEE&usp=sharing

ACTUALIZACIÓN 2

Ok, probé lo siguiente en la computadora de mi trabajo y obtuve el siguiente resultado:

 In [4]: store = pd.HDFStore('test0.h5','w') In [5]: for chunk in pd.read_csv('Train.csv', chunksize=10000): ...: store.append('df', chunk, index=False, data_columns=True) ...: Exception: cannot find the correct atom type -> [dtype->object,items->Index([fiB aseModel], dtype=object)] [fiBaseModel] column has a min_itemsize of [13] but it emsize [9] is required! 

Creo que sé lo que está pasando aquí. Si tomo la longitud máxima del campo fiBaseModel para el primer fragmento, obtengo esto:

 In [16]: lens = df.fiBaseModel.apply(lambda x: len(x)) In [17]: max(lens[:10000]) Out[17]: 9 

Y la segunda parte:

 In [18]: max(lens[10001:20000]) Out[18]: 13 

Por lo tanto, la tabla de almacenamiento se crea con 9 bytes para esta columna porque ese es el máximo de la primera parte. Cuando encuentra un campo de texto más largo en fragmentos posteriores, lanza la excepción.

Mis sugerencias para esto serían truncar los datos en fragmentos subsiguientes (con una advertencia) o permitir que el usuario especifique el almacenamiento máximo para la columna y truncar todo lo que la exceda. Tal vez los pandas ya pueden hacer esto, aún no he tenido tiempo de sumergirme profundamente en HDFStore .

ACTUALIZACIÓN 3

Intentando importar un conjunto de datos csv utilizando pd.read_csv. Paso un diccionario de todos los objetos al parámetro dtypes. Luego itero sobre el archivo y almaceno cada fragmento en el HDFStore pasando un gran valor para min_itemsize . Me sale la siguiente excepción:

 AttributeError: 'NoneType' object has no attribute 'itemsize' 

Mi código simple:

 store = pd.HDFStore('test0.h5','w') objects = dict((col,'object') for col in header) for chunk in pd.read_csv('Train.csv', header=0, dtype=objects, chunksize=10000, na_filter=False): store.append('df', chunk, min_itemsize=200) 

He intentado depurar e inspeccionar los elementos en el seguimiento de stack. Así es como se ve la tabla en la excepción:

 ipdb> self.table /df/table (Table(10000,)) '' description := { "index": Int64Col(shape=(), dflt=0, pos=0), "values_block_0": StringCol(itemsize=200, shape=(53,), dflt='', pos=1)} byteorder := 'little' chunkshape := (24,) autoIndex := True colindexes := { "index": Index(6, medium, shuffle, zlib(1)).is_CSI=False} 

ACTUALIZACIÓN 4

Ahora estoy tratando de determinar iterativamente la longitud de la cadena más larga en las columnas de objetos de mi dataframe. Así es como lo hago:

  def f(x): if x.dtype != 'object': return else: return len(max(x.fillna(''), key=lambda x: len(str(x)))) lengths = pd.DataFrame([chunk.apply(f) for chunk in pd.read_csv('Train.csv', chunksize=50000)]) lens = lengths.max().dropna().to_dict() In [255]: lens Out[255]: {'Backhoe_Mounting': 19.0, 'Blade_Extension': 19.0, 'Blade_Type': 19.0, 'Blade_Width': 19.0, 'Coupler': 19.0, 'Coupler_System': 19.0, 'Differential_Type': 12.0 ... etc... } 

Una vez que tengo el dictado de las longitudes máximas de cadena-columna, trato de pasarlo para min_itemsize a través del argumento min_itemsize :

 In [262]: for chunk in pd.read_csv('Train.csv', chunksize=50000, dtype=types): .....: store.append('df', chunk, min_itemsize=lens) Exception: cannot find the correct atom type -> [dtype->object,items->Index([Usa geBand, saledate, fiModelDesc, fiBaseModel, fiSecondaryDesc, fiModelSeries, fiMo delDescriptor, ProductSize, fiProductClassDesc, state, ProductGroup, ProductGrou pDesc, Drive_System, Enclosure, Forks, Pad_Type, Ride_Control, Stick, Transmissi on, Turbocharged, Blade_Extension, Blade_Width, Enclosure_Type, Engine_Horsepowe r, Hydraulics, Pushblock, Ripper, Scarifier, Tip_Control, Tire_Size, Coupler, Co upler_System, Grouser_Tracks, Hydraulics_Flow, Track_Type, Undercarriage_Pad_Wid th, Stick_Length, Thumb, Pattern_Changer, Grouser_Type, Backhoe_Mounting, Blade_ Type, Travel_Controls, Differential_Type, Steering_Controls], dtype=object)] [va lues_block_2] column has a min_itemsize of [64] but itemsize [58] is required! 

La columna ofensiva recibió un tamaño mínimo de 64, sin embargo, la excepción indica que se requiere un tamaño de artículo de 58. Esto puede ser un error?

En [266]: pd. version Out [266]: ‘0.11.0.dev-eb07c5a’

El enlace que proporcionaste funcionó bien para almacenar el marco. Columna por columna solo significa que especifique data_columns = True. Procesará las columnas individualmente y subirá sobre la ofensiva.

Diagnosticar

 store = pd.HDFStore('test0.h5','w') In [31]: for chunk in pd.read_csv('Train.csv', chunksize=10000): ....: store.append('df', chunk, index=False, data_columns=True) 

En producción, es probable que desee restringir data_columns a las columnas que desea consultar (también podría ser Ninguna, en cuyo caso puede consultar solo en el índice / columnas)

Actualizar:

Usted podría encontrarse con otro problema. read_csv convierte dtypes en función de lo que ve en cada fragmento, por lo que con un tamaño de trozo de 10,000, las operaciones de agregación fallaron porque los trozos 1 y 2 tenían datos de búsqueda de enteros en algunas columnas, luego en el trozo 3 tenías algo de NaN, por lo que flotaba. Especifique por adelantado los tipos de datos, use un tamaño de trozos más grande o ejecute sus operaciones dos veces para garantizar sus tipos de datos entre los trozos.

He actualizado pytables.py para tener una excepción más útil en este caso (además de informarle si una columna tiene datos incompatibles)

Gracias por el informe!