内置方法用于分块NumPy数组

时间:2018-12-29 17:55:00

标签: python python-3.x numpy dask

我在NetCDF4文件中有大量数据,我试图编写一个脚本来动态分块此数据以尽可能多地保存在内存中,对其进行计算并保存结果,然后继续进行操作。下一块。

我正在尝试做的一个例子。说我有一个像这样的数组:

import numpy as np
arr = np.random.randint(0, 10, (100, 15, 51))  # Call these x, y, and z coordinates

我只想一次读取十个x坐标,就像这样:

placeholder = 0
for i in range(10, 101, 10):
    tmp_array = arr[placeholder:i, :, :]
    # Do calculations here and save results to file or database
    placeholder += 10

是否有某种内置方法?在这个简单的示例中,它工作得很好,但是随着事情变得更加复杂,这似乎让我自己管理所有这些事情变得头疼。我知道Dask,但是在这种情况下这对我没有帮助,因为我没有对数据进行数组操作。尽管Dask如果也有解决此问题的方法对我可能会有用。

3 个答案:

答案 0 :(得分:1)

Dask文档显示了如何针对您想要的计算类型创建分块数组,对于hdf5文件:http://docs.dask.org/en/latest/array-creation.html#numpy-slicing。您的netCDF4情况可能会或可能不会完全一样,但是如果不是,则delayed后面的那部分将达到目的。

制作完数组之后,您将需要使用map_blocks方法来执行“对每个块执行一些操作”(这将获得一些返回的结果),在{{ 1}}属性,或使用.blocks对每个片段执行任意操作。究竟哪种方法适合您取决于您​​要实现的目标。

答案 1 :(得分:1)

您可以通过实现惰性生成器来减少复杂性并提高健壮性,该生成器封装您担心的计算,并在每个步骤仅返回块。也许是这样的:

def spliterate(buf, chunk):
    for start in range(0, buf.size, chunk):
        yield buf[start:start + chunk]

使用它非常简单:

for tmp in spliterate(arr, 10):
    # do calculations on tmp, don't worry about bookkeeping

答案 2 :(得分:0)

您可以使用np.split,它采用一个数组和一个块大小或一个用于执行拆分的索引列表。您的情况为np.split(arr, 10),将为您提供10个形状为(10, 15, 51)的阵列的列表。

请注意,如果无法将轴均等分割,则会引发异常,例如,如果您请求大小为9的块。如果要分割成几乎相等的块而不进行分割,则可以使用np.array_split代替。