如何排除HDFStore异常:找不到正确的atom类型

2024-09-28 21:17:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一些关于什么样的数据场景可以导致此异常的一般指导。我试过用各种方法来修改我的数据,但都没有用。在

我在google上搜索这个异常已经好几天了,经过几次google小组讨论,没有找到调试HDFStore Exception: cannot find the correct atom type的解决方案。我正在阅读一个混合数据类型的简单csv文件:

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)

存储数据帧的代码:

^{pr2}$

请注意,如果我在一次导入的数据帧上使用store.put,我可以成功地存储它,尽管速度很慢(我相信这是由于对象数据类型的pickle,即使对象只是字符串数据)。在

是否存在可能引发此异常的NaN值考虑因素?在

例外情况:

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

更新1

Jeff关于存储在数据帧中的列表的提示使我研究了嵌入的逗号。pandas.read_csv正在正确分析文件,并且在双引号中确实嵌入了一些逗号。所以这些字段本身不是python列表,但是文本中有逗号。以下是一些示例:

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

但是,当我从pd.read_csv文件chunks和append到我的HDFStore,我仍然得到相同的异常。当我尝试单独附加每个列时,会出现以下新异常:

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-><class 'pandas.core.series.Series'>,table->True,append->True,k
wargs->{'data_columns': True}]

我将继续排除故障。以下是数百条记录的链接:

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

更新2

好的,我在我的工作计算机上尝试了以下操作,得到了以下结果:

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!

我想我知道这里发生了什么。若我取第一个块的字段fiBaseModel的最大长度,我得到:

In [16]: lens = df.fiBaseModel.apply(lambda x: len(x))

In [17]: max(lens[:10000])
Out[17]: 9

第二块:

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

所以存储表是用9字节为这个列创建的,因为这是第一个块的最大值。当它在随后的块中遇到一个较长的文本字段时,它将抛出异常。在

对此,我的建议是要么截断后续块中的数据(带警告),要么允许用户为列指定最大存储空间,并截断任何超出该存储空间的内容。也许熊猫已经可以做到这一点,我还没有时间真正深入研究HDFStore。在

更新3

尝试使用导入csv数据集pd.read_csv文件. 我将所有对象的字典传递给dtypes参数。然后,我遍历该文件,并将每个块存储到HDFStore中,为min_itemsize传递一个大值。我有以下例外:

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

我的简单代码:

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)

我试着调试并检查了堆栈跟踪中的项。以下是例外情况下的表格:

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}

更新4

现在我尝试迭代地确定dataframe对象列中最长字符串的长度。我就是这样做的:

    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... }

有了max string column length的dict后,我尝试通过min_itemsize参数将其传递给append

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!

向有问题的列传递的min_itemsize为64,但异常状态为itemsize为58是必需的。这可能是个虫子?在

在[266]中:pd.版本 输出[266]:'0.11.0.dev-eb07c5a'


Tags: csv数据inforreadobjecttypenull
1条回答
网友
1楼 · 发布于 2024-09-28 21:17:20

你提供的链接可以很好地存储框架。一列一列只意味着specify data_columns=True。它将单独处理列,并在有问题的列上引发。在

诊断

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)

在生产环境中,您可能希望将data_列限制为要查询的列(也可以是None,在这种情况下,您只能查询索引/列)

更新:

你可能会遇到另一个问题。read_csv根据在每个块中看到的内容转换数据类型, 因此,当chunksize为10000时,append操作失败,因为chunk1和2 在一些列中查找整型数据,然后在块3中有一些NaN,所以这是因为浮动。 预先指定数据类型,使用较大的chunksize,或者运行两次操作 以保证块之间的数据类型。在

我已经更新了pytables.py在这种情况下有一个更有用的例外(以及 如告诉您某列是否包含不兼容的数据)

谢谢你的报告!在

相关问题 更多 >