【问题标题】:Appending to HDFStore fails with "cannot match existing table structure"附加到 HDFStore 失败并显示“无法匹配现有表结构”
【发布时间】:2020-08-01 15:23:16
【问题描述】:

最终的解决方案是使用 read_csv 的“converters”参数并在将其添加到 DataFrame 之前检查每个值。最终在超过 80GB 的原始数据中只有 2 个损坏的值。

参数如下:

converters={'XXXXX': self.parse_xxxxx}

还有像这样的小静态辅助方法:

@staticmethod
def parse_xxxxx(input):
    if not isinstance(input, float):
        try:
            return float(input)
        except ValueError:
            print "Broken Value: ", input
            return float(0.0)
    else:
         return input

在尝试阅读 ca.将 40GB+ 的 csv 数据转换为 HDF 文件我遇到了一个令人困惑的问题。读取大约 1GB 后,整个过程失败并出现以下错误

File "/usr/lib/python2.7/dist-packages/pandas/io/pytables.py", line 658, in append
    self._write_to_group(key, value, table=True, append=True, **kwargs)
  File "/usr/lib/python2.7/dist-packages/pandas/io/pytables.py", line 923, in write_to_group
    s.write(obj = value, append=append, complib=complib, **kwargs)
  File "/usr/lib/python2.7/dist-packages/pandas/io/pytables.py", line 2985, in write **kwargs)
  File "/usr/lib/python2.7/dist-packages/pandas/io/pytables.py", line 2675, in create_axes
    raise ValueError("cannot match existing table structure for [%s] on appending data" % items)
ValueError: cannot match existing table structure for [Date] on appending data

我使用的read_csv调用如下:

pd.io.parsers.read_csv(filename, sep=";|\t", compression='bz2', index_col=False, header=None, names=['XX', 'XXXX', 'Date', 'XXXXX'], parse_dates=[2], date_parser=self.parse_date, low_memory=False, iterator=True, chunksize=self.input_chunksize, dtype={'Date': np.int64})

当我将 dtypte 显式设置为 int64 时,为什么新块的“日期”列不适合现有列?

感谢您的帮助!

这是解析日期的函数:

@staticmethod
def parse_date(input_date):
       import datetime as dt
       import re

       if not re.match('\d{12}', input_date):
           input_date = '200101010101'

        timestamp = dt.datetime.strptime(input_date, '%Y%m%d%H%M')
        return timestamp

遵循 Jeff 的一些提示后,我可以提供有关我的问题的更多详细信息。这是我用来加载 bz2 编码文件的完整代码:

iterator_data = pd.io.parsers.read_csv(filename, sep=";|\t", compression='bz2', index_col=False, header=None,
                                               names=['XX', 'XXXX', 'Date', 'XXXXX'], parse_dates=[2],
                                               date_parser=self.parse_date, iterator=True,
                                               chunksize=self.input_chunksize, dtype={'Date': np.int64})
for chunk in iterator_data:
    self.data_store.append('huge', chunk, data_columns=True)
    self.data_store.flush()

csv 文件遵循以下模式:{STRING};{STRING};{STRING}\t{INT}

ptdump -av对输出文件调用的输出如下:

ptdump -av datastore.h5
/ (RootGroup) ''
  /._v_attrs (AttributeSet), 4 attributes:
   [CLASS := 'GROUP',
    PYTABLES_FORMAT_VERSION := '2.0',
    TITLE := '',
    VERSION := '1.0']
/huge (Group) ''
  /huge._v_attrs (AttributeSet), 14 attributes:
   [CLASS := 'GROUP',
    TITLE := '',
    VERSION := '1.0',
    data_columns := ['XX', 'XXXX', 'Date', 'XXXXX'],
    encoding := None,
    index_cols := [(0, 'index')],
    info := {'index': {}},
    levels := 1,
    nan_rep := 'nan',
    non_index_axes := [(1, ['XX', 'XXXX', 'Date', 'XXXXX'])],
    pandas_type := 'frame_table',
    pandas_version := '0.10.1',
    table_type := 'appendable_frame',
    values_cols := ['XX', 'XXXX', 'Date', 'XXXXX']]
/huge/table (Table(167135401,), shuffle, blosc(9)) ''
  description := {
  "index": Int64Col(shape=(), dflt=0, pos=0),
  "XX": StringCol(itemsize=16, shape=(), dflt='', pos=1),
  "XXXX": StringCol(itemsize=16, shape=(), dflt='', pos=2),
  "Date": Int64Col(shape=(), dflt=0, pos=3),
  "XXXXX": Int64Col(shape=(), dflt=0, pos=4)}
  byteorder := 'little'
  chunkshape := (2340,)
  autoIndex := True
  colindexes := {
    "Date": Index(6, medium, shuffle, zlib(1)).is_CSI=False,
    "index": Index(6, medium, shuffle, zlib(1)).is_CSI=False,
    "XXXX": Index(6, medium, shuffle, zlib(1)).is_CSI=False,
    "XXXXX": Index(6, medium, shuffle, zlib(1)).is_CSI=False,
    "XX": Index(6, medium, shuffle, zlib(1)).is_CSI=False}
  /huge/table._v_attrs (AttributeSet), 23 attributes:
   [XXXXX_dtype := 'int64',
    XXXXX_kind := ['XXXXX'],
    XX_dtype := 'string128',
    XX_kind := ['XX'],
    CLASS := 'TABLE',
    Date_dtype := 'datetime64',
    Date_kind := ['Date'],
    FIELD_0_FILL := 0,
    FIELD_0_NAME := 'index',
    FIELD_1_FILL := '',
    FIELD_1_NAME := 'XX',
    FIELD_2_FILL := '',
    FIELD_2_NAME := 'XXXX',
    FIELD_3_FILL := 0,
    FIELD_3_NAME := 'Date',
    FIELD_4_FILL := 0,
    FIELD_4_NAME := 'XXXXX',
    NROWS := 167135401,
    TITLE := '',
    XXXX_dtype := 'string128',
    XXXX_kind := ['XXXX'],
    VERSION := '2.6',
    index_kind := 'integer']

经过大量额外调试后,我遇到了以下错误:

ValueError: invalid combinate of [values_axes] on appending data [name->XXXX,cname->XXXX,dtype->int64,shape->(1, 10)] vs current table [name->XXXX,cname->XXXX,dtype->string128,shape->None]

然后我尝试通过添加修改 read_csv 调用来解决此问题,以便强制 XXXX 列使用正确的类型,但刚刚收到相同的错误:

dtype={'XXXX': 's64', 'Date': dt.datetime})

read_csv 是否忽略了 dtype 设置或者我在这里遗漏了什么?

当读取块大小为 10 的数据时,最后 2 个 chunk.info() 调用给出以下输出:

Int64Index: 10 entries, 0 to 9
Data columns (total 4 columns):
XX         10  non-null values
XXXX       10  non-null values
Date       10  non-null values
XXXXX      10  non-null values
dtypes: datetime64[ns](1), int64(1), object(2)<class 'pandas.core.frame.DataFrame'>
Int64Index: 10 entries, 0 to 9
Data columns (total 4 columns):
XX         10  non-null values
XXXX       10  non-null values
Date       10  non-null values
XXXXX      10  non-null values
dtypes: datetime64[ns](1), int64(2), object(1)

我使用的是熊猫版本0.12.0

【问题讨论】:

  • 以及显示现有表和您尝试存储的内容的示例(显示 df.info()),以及熊猫版本
  • stackoverflow.com/questions/15488809/… 可能会帮助您排除故障
  • 还请显示不会精确的读写代码
  • 也显示 ptdump -av
  • 我得到了很多额外的信息,但 read_csv 似乎忽略了我设置的 dtypes。

标签: python pandas pytables


【解决方案1】:

好的,你有几个问题:

  • 当指定要传递给read_csv的dtypes时,它们必须是numpy dtypes;并且字符串 dtypes 被转换为 object dtype(所以 s64 不做任何事情)。 datetime 也没有,这就是 parse_dates 的用途。

  • 1234563这是你的问题。 (我认为错误信息可能会有些混乱,IIRC 在更高版本的 pandas 中已修复)。

因此,您需要使每个块中的 dtypes 都相同。您可能在该特定列中有混合数据。一种方法是指定dtype = { column_that_is_bad : 'object' }。另一种方法是在该列上使用convert_objects(convert_numeric=True) 将所有非数字值强制为nan(这也会将列的dtype 更改为float64)。

【讨论】:

  • 即使将 dtype 更改为:dtype={'XX': 'object', 'XXXX': 'object', 'Date': 'object', 'XXXXX': 'uint64'} ) 升级到 Pandas 0.13.1 我得到这个: ValueError: invalid combine of [values_axes] on appending data [name->XXXXX,cname->XXXXX,dtype->float64,shape->(1, 10000000)] vs 当前表[name->XXXXX,cname->XXXXX,dtype->int64,shape->无]
  • 在将它们写入 HDF 之前,您需要符合 dtypes,在编写它们之前查看每个块的 df.dtypes。某些数据正在更改它们(例如,您可能在一个中缺少值,但在另一个中没有)。您需要强制转换为正确的格式。
  • 混合数据类型也是我的问题。从 pandas 0.20.3 for hdf 开始,这个令人困惑的错误消息仍然存在
猜你喜欢
  • 2018-05-02
  • 1970-01-01
  • 2018-07-15
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
相关资源
最近更新 更多