我有一个大的 dask 数组 (labeled_arr
),它实际上是一个带标签的光栅图像(dtype 是 int64)。我想使用 rasterio 将标记区域转换为多边形并将它们组合成一个多边形列表(或只有一个几何列的地理系列)。这是单个数组上的一项简单任务,但我无法弄清楚如何告诉 dask 我希望它对每个 block 执行此操作并返回不是数组的内容。
应用于每个 block 的函数:
def get_polys(labeled_blocks):
polys = list(poly[0]['coordinates'][0] for poly in rasterio.features.shapes(
labeled_blocks.astype('int32'), transform=trans))[:-1]
# Note: rasterio.features.shapes returns an iterator, hence the conversion to a list here
return polys
尝试让 dask 执行此操作的代码行:
test_polygons = da.blockwise(get_polys, '', labeled_arr, 'ij')
test_polygons.compute()
其中 labeled_arr
是输入分块 dask 数组。
按原样运行会返回一个错误,提示我必须为 da.blockwise
指定数据类型。指定 dtype 会返回 AttributeError,因为输出列表类型没有 dtype 属性。我发现了 meta
关键字,但仍然无法获得将我的输出转换为系列或列表的正确语法。
我不依附于上述方法,但我的总体目标是:采用标记的、分块的 dask 数据阵列(它并不完全适合内存),根据每个 block 的计算提取一个列表,并生成一个串联的列表(或 pandas 数据对象),其中包含我原始分块数组中所有 block 的输出。
最佳答案
这可能有效:
import dask
import dask.array as da
# we expect to see 4 blocks here
test_array = da.random.random((4, 4), chunks=(2, 2))
@dask.delayed
def my_func(block):
# do something fancy
return list(block)
results = dask.compute([my_func(x) for x in test_array.to_delayed().ravel()])
如您所述,问题是 list
没有 dtype
。解决此问题的一种方法是将 list
转换为 np.array
,但我不确定这是否适用于所有 geometry
对象(对于 Points
应该没问题,但由于长度不同,多边形可能会有问题)。由于您对将这些几何图形强制放入数组不感兴趣,因此最好将单个 block 视为 delayed
对象,一次将它们送入您的函数(但跨工作程序/进程缩放)。
关于python - 从 dask 数组产生矢量输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66232232/