问题

如何在不对数据进行中间复制的情况下将数据从N x N x N x... h5py数据集复制到一维标准Python列表中?

我可以想到几种使用中间副本的方法。例如:

import h5py
import numpy as np

# initialize list, put some initial data in it
myList = ['foo']

# open up an h5py dataset from a file on disk
myFile = h5py.File('/path-to-my-data', 'r')
myData = myFile['bar']
myData.shape        # returns, for example, (5,15,7)

# copy dataset over to a numpy array
arr = np.zeros(myData.shape)
myData.read_direct(arr)

# finally, add data from copied dataset to myList
myList.extend(arr.flatten())

可以在没有中间副本到numpy数组的情况下完成此操作吗?

一些背景

(除非您很好奇,否则您绝对不必阅读此书)

我正在尝试通过其Python API将数据从HDF5文件复制到 Protocol Buffer 文件。这些都是用于编写自己的复杂的,可序列化的数据结构的库/框架。就其Python API而言,HDF5假装其数组为numpy数组,而 Protocol Buffer 假装其数组为标准1D Python列表(不幸的是, Protocol Buffer 中没有对简单多维数组的 native 支持)。因此,我需要将h5py数据集转换为Python列表。

编辑

有人要求澄清我的意思



我的意思是,h5py数据集向用户公开的界面类似于numpy数组公开的界面,而Python Protobuf重复数字字段公开的界面与标准Python列表的相似。但是,它们都没有实现其原型(prototype)的完整行为,甚至没有完整接口(interface)。例如,h5py数据集没有.flatten()方法,如果尝试将其他列表分配为元素,则Pybuf重复字段会提示(例如myBuf.repIntField[2] = [1,2,3]将始终引发错误)。

这是Pybuf documentation的相关行:



以及来自h5py documentation的相关行(添加了强调):

最佳答案

对于numpy数组,我建议使用ndarray.flat但h5py数据集没有flat/flatten属性。

您可以创建一个生成器,将生成的块以numpy数组的形式带入内存,然后从展平的值中产生值。然后可以将其转换为列表。例如,仅沿外部尺寸进行分块:

def yield_chunks(x):
    for chunk in iter(x):
        yield chunk.flat

myGenerator = itertools.chain(yield_chunk(arr))
myGenerator将根据arr生成单个值。您可以使用list(myGenerator)将其转换为列表。

10-06 10:28