【问题标题】:How to parallelize writing to same cell in a numpy array?如何并行写入numpy数组中的同一单元格?
【发布时间】:2020-10-06 20:11:08
【问题描述】:

背景:我在 2D 空间中有数百万个点,(x_position, y_position, value) 与每个点相关联。我试图通过创建一个图像来总结这些点,其中每个像素可以包含多个点。总而言之,每个像素存储图像中(x_pixel, y_pixel) 位置处values 的总和。

问题:我怎样才能有效地做到这一点?目前,我的代码是这样的:

image = np.zeros((4096,4096))
for each point in data:
    x_pixel, y_pixel = convertPointPos2PixelPos(point)
    image[x_pixel, y_pixel] += point.getValue()

但此代码完成的 ETA 是 450 小时,这是不可接受的。有没有办法并行化这个?代码多次写入同一个image[x,y] 索引。我发现建议使用 multiprocessing 的 StackOverflow 帖子,但我认为需要 lock 来防止竞争条件意味着这将花费与没有并行化一样多的时间。

【问题讨论】:

  • 这很大程度上取决于convertPointPos2PixelPos是否可以向量化。在最坏的情况下,您正在使用旨在处理数组的方法进行迭代,而不是像 in this case
  • 重点是什么?什么是数据?请发布 MCVE。

标签: python numpy image-processing parallel-processing 2d


【解决方案1】:

假设您想要常规网格上的某些内容,您可以使用简单的除法来对数据进行分类。这是一个例子:

size = (4096, 4096)
data = np.random.rand(100000000, 3)
image = np.zeros(size)

coords = data[:, :2]
min = coords.min(0)
max = coords.max(0)

index = np.floor_divide(coords - min, (max - min) / np.subtract(size, 1), out=np.empty(coords.shape, dtype=int), casting='unsafe')

index 现在是image 的索引数组,您要在其中添加相应的值。您可以使用np.add.at 进行无缓冲添加:

np.add.at(image, tuple(index.T), data[:, -1])

如果您的数据范围比坐标的边界框定义得更好,您可以通过不计算 coord.max()coord.min() 来节省一点时间。

结果是这样的:

整个操作在我的中等功率机器上花费 6.4 秒,获得 10M 点,包括对 plt.imshowplt.colorbar 的调用和运行前的垃圾收集。

使用 IPython 中的 %%timeit 单元魔法收集时间。

无论哪种方式,您都还不到 450 小时。即使您的坐标变换不是线性分箱,我希望您可以在合理的时间内运行,只要您正确地对其进行矢量化。此外,多处理不太可能给您带来巨大的提升,因为它需要复制数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多