You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:Dask map_overlap处理缩放后数组的分块不匹配报错解决

Dask map_overlap块不匹配错误解决

需求说明

我有两个类矩阵变量:维度(100,100)的a和维度(200,200)的b。需要先将a放大2倍以匹配b的尺寸,再通过Dask的map_overlap函数执行自定义计算并指定重叠区域,最终得到与b尺寸一致的结果。

复现代码

import dask.array as da
import numpy as np
from scipy.ndimage import zoom

data = da.ones((40, 140,140), chunks=(10, 40,40))
data2 = da.ones((80, 280, 280), chunks=(10, 40,40))
data_upsampled = da.map_blocks(lambda x: zoom(x,2), data, dtype = np.uint16, chunks=(20,80,80))

res = da.map_overlap(lambda x,y: x+y, data_upsampled, data2, depth = (5,10,10), boundary="constant")

错误信息

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[7], line 10
      7 data2 = da.ones((80, 280, 280), chunks=(10, 40,40))
      8 data_upsampled = da.map_blocks(lambda x: zoom(x,2), data, dtype = np.uint16, chunks=(20,80,80))
---> 10 res = da.map_overlap(lambda x,y: x+y, data_upsampled, data2, depth = (5,10,10), boundary="constant")
     11 #data_upsampled.to_hdf5('myfile.hdf5', '/up_sampled')

File \AppData\Local\anaconda3\envs\napari\lib\site-packages\dask\array\overlap.py:693, in map_overlap(func, depth, boundary, trim, align_arrays, allow_rechunk, *args, **kwargs)
    690 if align_arrays:
    691     # Reverse unification order to allow block broadcasting
    692     inds = [list(reversed(range(x.ndim))) for x in args]
--> 693     _, args = unify_chunks(*list(concat(zip(args, inds))), warn=False)
    695 # Escape to map_blocks if depth is zero (a more efficient computation)
    696 if all([all(depth_val == 0 for depth_val in d.values()) for d in depth]):

File \AppData\Local\anaconda3\envs\napari\lib\site-packages\dask\array\core.py:3971, in unify_chunks(*args, **kwargs)
   3968     else:
   3969         nameinds.append((a, ind))
-> 3971 chunkss = broadcast_dimensions(nameinds, blockdim_dict, consolidate=common_blockdim)
   3972 nparts = math.prod(map(len, chunkss.values()))
   3974 if warn and nparts and nparts >= max_parts * 10:

File \AppData\Local\anaconda3\envs\napari\lib\site-packages\dask\blockwise.py:1467, in broadcast_dimensions(argpairs, numblocks, sentinels, consolidate)
   1464 g2 = {k: v - set(sentinels) if len(v) > 1 else v for k, v in g.items()}
...
   3883 # burned through all of the chunk tuples.
   3884 # For efficiency's sake we reverse the lists so that we can pop off the end
   3885 rchunks = [list(ntd)[::-1] for ntd in non_trivial_dims]

ValueError: ('Chunks do not add up to same value', {(40, 40, 40, 40, 40, 40, 40), (80, 80, 80, 80)})

问题原因

map_overlap要求输入数组的块结构(chunks)在对应维度上必须完全兼容:

  • data2的第二、三维块划分是(40,40,40,40,40,40,40)(7个40,总和280)
  • data_upsampled的第二、三维实际块划分是(80,80,80,40)(与指定的(80,80,80,80)矛盾,因为原维度140放大2倍是280,无法被4个80整除)
    两者的块划分无法对齐,导致报错。

解决方案

核心是让两个输入数组的块结构完全一致,有两种实现方式:

方式1:调整data2的块结构匹配data_upsampled

import dask.array as da
import numpy as np
from scipy.ndimage import zoom

data = da.ones((40, 140,140), chunks=(10, 40,40))
# 调整data2的块结构,与data_upsampled的块划分对齐
data2 = da.ones((80, 280, 280), chunks=(10, [80,80,80,40], [80,80,80,40]))
data_upsampled = da.map_blocks(lambda x: zoom(x,2), data, dtype = np.uint16, chunks=(20,80,80))

res = da.map_overlap(lambda x,y: x+y, data_upsampled, data2, depth=(5,10,10), boundary="constant")

方式2:将data_upsampled重新分块匹配data2

import dask.array as da
import numpy as np
from scipy.ndimage import zoom

data = da.ones((40, 140,140), chunks=(10, 40,40))
data2 = da.ones((80, 280, 280), chunks=(10, 40,40))
data_upsampled = da.map_blocks(lambda x: zoom(x,2), data, dtype = np.uint16)
# 重新分块,对齐data2的块结构
data_upsampled = data_upsampled.rechunk(chunks=(10,40,40))

res = da.map_overlap(lambda x,y: x+y, data_upsampled, data2, depth=(5,10,10), boundary="constant")

两种方式都能让数组块结构对齐,确保map_overlap正常执行。

内容的提问来源于stack exchange,提问作者Nim.Moj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:05:55