14

我有一个由 PyTables 生成的相当大的 HDF5 文件,我试图在集群上读取它。当我阅读单个块时,我遇到了 NumPy 的问题。让我们来看这个例子:

HDF5 文件中数组的总形状是,

In [13]: data.shape
Out[13]: (21933063, 800, 3)

此数组中的每个条目都是一个np.float64.

我让每个节点读取 size 的切片(21933063,10,3)。不幸的是,NumPy 似乎无法一次读取所有 2100 万个子切片。我试图通过将这些切片分成 10 个大小的切片按顺序执行此操作(2193306,10,3),然后使用以下 reduce 使事情正常工作:

In [8]: a = reduce(lambda x,y : np.append(x,y,axis=0), [np.array(data[i*      \
        chunksize: (i+1)*chunksize,:10],dtype=np.float64) for i in xrange(k)])
In [9]:

哪里1 <= k <= 10chunksize = 2193306。此代码适用于k <= 9;否则我会得到以下信息:

In [8]: a = reduce(lambda x,y : np.append(x,y,axis=0), [np.array(data[i*      \
        chunksize: (i+1)*chunksize,:10],dtype=np.float64) for i in xrange(k)])
Floating point exception
home@mybox  00:00:00  ~
$

我尝试使用 Valgrind 的memcheck工具来弄清楚发生了什么,似乎 PyTables 是罪魁祸首。跟踪中显示的两个主要文件是libhdf5.so.6一个与blosc.

另外,请注意,如果我有k=8,我会得到:

In [12]: a.shape
Out[12]: (17546448, 10, 3)

但是如果我附加最后一个子切片,我会得到:

In [14]: a = np.append(a,np.array(data[8*chunksize:9*chunksize,:10],   \
         dtype=np.float64))
In [15]: a.shape
Out[15]: (592192620,)

有没有人知道该怎么做?谢谢!

4

1 回答 1

1

您之前是否尝试过分配这么大的数组(如 DaveP 建议的那样)?

In [16]: N.empty((21000000,800,3))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
...
ValueError: array is too big.

这是在 32 位 Python 上。您实际上需要 20e6*800*3*8/1e9=384 GB 的内存!一个 Float64 需要 8 个字节。你真的需要一次整个阵列吗?

抱歉,没有正确阅读帖子。

您的具有 k=8 个子切片的数组已经大约 4.1 GByte 大。也许这就是问题所在?

如果最后一个维度只使用8而不是10 ,它是否有效?

另一个建议,我会先尝试调整数组的大小,然后将其填满:

a = zeros((4,8,3))
a = resize(a, (8,8,3))
a[4:] = ones((4,8,3))
于 2011-10-13T11:08:24.460 回答