【问题标题】:Writing data to resized hdf5 dataset fails in surprising ways将数据写入调整大小的 hdf5 数据集以令人惊讶的方式失败
【发布时间】:2019-07-19 05:36:39
【问题描述】:

我正在尝试创建一个我最初不知道完整大小的数据集。

我使用以下属性创建我的数据集。

file['data'].create_dataset(
   name='test', shape=(10, len(arr1)), 
   maxshape=(10, None), dtype=float,
   scaleoffset=3, chunks=True, 
   compression='gzip', compression_opts=4, fillvalue=np.nan)

形状的最终维度是我需要扩展的维度(由第一个输入给出的初始形状)。

当我为 arr2 调整数据集的大小时,一切正常,但是当我尝试将它扩展到更大的 arr3 大小时,事情开始变得奇怪。

如果我逐步调整大小并一个接一个地写入每个数组,则数据集的内容会损坏,并且第一个数组长度之外的值 (arr1),在本例中为 100,将写入填充值 ( nan),而前 100 个值被正确存储。请注意,在调整大小和写入arr2 时不会发生这种情况,这将正确写入arr2 的所有值,同时使用nan 扩展第一个条目。

我也尝试过手动增加块大小,但是当我编写较小的数组时,无法使用正确的填充值(默认为 0,而不是 nan),除非块大小显式大于最大数组,最大数组仍然被截断为块大小之外的填充值。

arr1 = np.arange(0, 100, step=1, dtype=float)
arr2 = np.arange(0, 233, step=1, dtype=float)
arr3 = np.arange(0, 50000, step=1, dtype=float)

file = h5py.File(my_data_file, 'w')
file.create_group('data')
file['data'].create_dataset(
   name='test', shape=(10, len(arr1)), 
   maxshape=(10, None), dtype=float,
   scaleoffset=3, chunks=True, 
   compression='gzip', compression_opts=4, fillvalue=np.nan)

file['data']['test'][0, :len(arr1)] = arr1
try:
    file['data']['test'][1, :len(arr2)] = arr2
except TypeError as e:
    print('New data too large for old dataset, resizing')
    file['data']['test'].resize((10, len(arr2)))
    file['data']['test'][1, :len(arr2)] = arr2

如果我停在这里,一切看起来都像预期的那样,但是当我运行以下代码时出现了主要问题。

try:
    file['data']['test'][2, :len(arr3)] = arr3
except TypeError as e:
    print('New data too large for old dataset, resizing')
    file['data']['test'].resize((10, len(arr3)))
    file['data']['test'][2, :len(arr3)] = arr3

【问题讨论】:

    标签: python hdf5 h5py


    【解决方案1】:

    我进行了一些测试来诊断。首先,我运行了 3 个单独的步骤,我看到的行为与您描述的不同。
    测试 1:仅限 arr1
    仅将 arr1 添加到第 0 行并关闭文件:
    第 0 行具有正确的 arr1 值,第 1-9 行填充有 0.0,而不是 NaN
    测试 2:arr1 和 arr2
    arr1 添加到第 0 行,调整大小,然后将 arr2 添加到第 1 行,然后关闭文件:
    对于 0-99 列:填充第 0 行和第 1 行,第 2-9 行填充 0.0,而不是 NaN。 100+ 列都是=NaN,所有行。请注意,arr2 值 > 99 不在文件中。
    测试 3:arr1、arr2、arr3
    按照上述过程加载所有 3 个数组:
    与测试 2 类似的结果:对于 0-99 列:填充第 0、1、2 行,用 0.0 填充第 3-9 行,而不是 NaN。 100+ 列都是=NaN,对于所有行。请注意,arr2arr3 值 > 99 不在文件中。

    然后我在修改create_dataset()后重新运行Test 3;删除以下参数:scaleoffset=3, chunks=True, compression='gzip', compression_opts=4。 生成的 HDF5 文件看起来与预期完全一样,NaN 处处没有添加数据(在第 0 行,第 100+ 列;第 1 行,第 233+ 列,以及第 3-9 行中的所有列)。请参阅下面的修改调用:

    h5f['data'].create_dataset(
       name='test', shape=(10, len(arr1)), 
       maxshape=(10, None), dtype=float, fillvalue=np.nan) 
    

    我对 4 个已删除的参数了解得不够多,无法解释为什么会这样 - 只是它确实如此。

    【讨论】:

    • 感谢您的回复,进一步查看文档似乎scaleoffset 选项不适用于特殊的浮点类型值(即InfNaN)。我相信当数据被“分块”时,它会将NaN 转换为 0,尽管仍然不清楚为什么不是所有列值(即arr2arr3 值 > 99)都被正确存储。
    • 另一个资源是h5py Google Group。 h5py 开发人员回复了一些帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2011-08-04
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多