6

假设我有一个包含数千个 GRIB 文件的目录。我想将这些文件加载​​到 dask 数组中,以便查询它们。我该怎么做呢?下面的尝试似乎有效,但它需要打开每个 GRIB 文件,并且需要很长时间才能运行和我的所有内存。肯定有更好的办法。

我的尝试:

import dask.array as da
from dask import delayed
import gdal
import glob
import os


def load(filedir):
    files = sorted(glob.glob(os.path.join(filedir, '*.grb')))
    data = [da.from_array(gdal.Open(f).ReadAsArray(), chunks=[500,500,500], name=f) for f in files]
    return da.stack(data, axis=0)

file_dir = ...
array = load(file_dir)
4

1 回答 1

6

最好的方法是使用dask.delayed. 在这种情况下,您将创建一个延迟函数来读取数组,然后使用该函数从这些delayed对象组成一个 dask 数组。da.from_delayed类似于以下内容:

# This function isn't run until compute time
@dask.delayed(pure=True)
def load(file):
    return gdal.Open(file).ReadAsArray()


# Create several delayed objects, then turn each into a dask
# array. Note that you need to know the shape and dtype of each
# file
data = [da.from_delayed(load(f), shape=shape_of_f, dtype=dtype_of_f)
        for f in files]

x = da.stack(data, axis=0)

请注意,这为加载每个文件创建了一个任务。如果单个文件很大,您可能希望自己在load函数中将它们分块。我对 gdal 不熟悉,但是通过简要了解该ReadAsArray方法,这可能与// /xoff参数yoff(不确定)是可行的。您必须自己编写此代码,但它对于大文件可能更高效。xsizeysize

或者,您可以使用上面的代码,然后调用rechunk重新分块成更小的块。这仍然会导致在单个任务中读取每个文件,但后续步骤可以使用较小的块。这是否值得取决于您个人文件的大小。

x = x.rechunk((500, 500, 500))  # or whatever chunks you want
于 2017-05-08T18:27:24.817 回答