Python Xarray:内存不足错误(调用Dask支持的Xarray的堆栈方法时,任务被系统终止)

Python Xarray:内存不足错误(调用Dask支持的Xarray的堆栈方法时,任务被系统终止),python,dask,python-xarray,dask-distributed,Python,Dask,Python Xarray,Dask Distributed,我试图解决一个关于SO post()的问题,并以下面提供的代码结束 问题在于,在该代码中,调用DataArray的stack方法会导致内存不足错误 我的问题是: 我想知道为什么连在一起的对象(一个xarray.DataArray)的堆栈方法不能成功完成,即使这个DataArray是由Dask支持的(所以它不应该耗尽内存)?为什么测试机器内存不足,任务被系统终止 运行此代码时发生的事情的一点总结: 代码平稳运行,直到行stacked=concatenated.stack(sample=('y','

我试图解决一个关于SO post()的问题,并以下面提供的代码结束

问题在于,在该代码中,调用
DataArray
stack
方法会导致内存不足错误

我的问题是:

我想知道为什么连在一起的
对象(一个
xarray.DataArray
)的堆栈方法不能成功完成,即使这个DataArray是由Dask支持的(所以它不应该耗尽内存)?为什么测试机器内存不足,任务被系统终止

运行此代码时发生的事情的一点总结:

代码平稳运行,直到行
stacked=concatenated.stack(sample=('y','x','time'))

此时,内存使用率不断增加,直到达到几乎100%,任务被系统终止。 该代码是在一台具有8GB RAM的机器上执行的。 我认为它不会耗尽内存,因为
连接的
是一个由Dask支持的
xarray。数据阵列
。但确实如此

我对这段代码做了各种更改,比如使用延迟操作、更改块大小、使用Dask方法而不是xarray方法等等,但都没有成功

我想到了两种可能发生的事情:

  • 堆栈操作不支持Dask
  • 堆栈操作是由Dask支持的,但即使是Dask也需要最少的内存量,而这个内存量无法容纳
有人知道这里发生了什么,以及如何解决这个问题吗

结束注释:

您可以改变
nrows
ncols
以更改连接的
的大小。
例如,设置
nrows=10000
而不是
nrows=20000
将使其大小减少一半

为了确保DataArray是Dask支持的,我还尝试将
连接的
保存到netcdf,并使用
chunks
参数加载它。我尝试了不同的块值,但同样没有成功:

concatenated.to_netcdf("concatenated.nc")
concatenated = xr.open_dataarray("concatenated.nc", chunks=10)
chunks
参数使用较小的值只会导致 有更多的时间耗尽内存

代码如下:

import numpy as np
import dask.array as da
import xarray as xr
from numpy.random import RandomState

nrows = 20000
ncols = 20000
row_chunks = 500
col_chunks = 500


# Create a reproducible random numpy array
prng = RandomState(1234567890)
numpy_array = prng.rand(1, nrows, ncols)

data = da.from_array(numpy_array, chunks=(1, row_chunks, col_chunks))


def create_band(data, x, y, band_name):

    return xr.DataArray(data,
                        dims=('band', 'y', 'x'),
                        coords={'band': [band_name],
                                'y': y,
                                'x': x})

def create_coords(data, left, top, celly, cellx):
    nrows = data.shape[-2]
    ncols = data.shape[-1]
    right = left + cellx*ncols
    bottom = top - celly*nrows
    x = np.linspace(left, right, ncols) + cellx/2.0
    y = np.linspace(top, bottom, nrows) - celly/2.0
    
    return x, y


x, y = create_coords(data, 1000, 2000, 30, 30)

bands = ['blue', 'green', 'red', 'nir']
times = ['t1', 't2', 't3']
bands_list = [create_band(data, x, y, band) for band in bands]

src = []

for time in times:

    src_t = xr.concat(bands_list, dim='band')\
                    .expand_dims(dim='time')\
                    .assign_coords({'time': [time]})

    src.append(src_t)


concatenated = xr.concat(src, dim='time')
print(concatenated)
# computed = concatenated.compute() # "computed" is ~35.8GB

# All is fine until here
stacked = concatenated.stack(sample=('y','x','time'))

# After stack we'd like to transpose
transposed = stacked.T