Python 如何并行写入numpy数组中的同一单元格?

Python 如何并行写入numpy数组中的同一单元格?,python,numpy,image-processing,parallel-processing,2d,Python,Numpy,Image Processing,Parallel Processing,2d,背景:我在二维空间中有数百万个点,每个点都与(x\u位置,y\u位置,值)关联。我试图通过创建一个图像来总结这些点,每个像素可以包含多个点。总之,每个像素在图像中的(x\u像素,y\u像素)位置存储值的总和 问题:我如何才能有效地做到这一点?目前,我的代码执行如下操作: image = np.zeros((4096,4096)) for each point in data: x_pixel, y_pixel = convertPointPos2PixelPos(point) i

背景:我在二维空间中有数百万个点,每个点都与
(x\u位置,y\u位置,值)
关联。我试图通过创建一个图像来总结这些点,每个像素可以包含多个点。总之,每个像素在图像中的
(x\u像素,y\u像素)
位置存储
值的总和

问题:我如何才能有效地做到这一点?目前,我的代码执行如下操作:

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

但该代码完成的预计到达时间为450小时,这是不可接受的。有没有办法将其并行化?代码多次写入同一
图像[x,y]
索引。我发现StackOverflow帖子建议使用
多处理
,但我认为需要
锁定
以防止竞争条件,这意味着这将花费与不进行并行化一样多的时间。

假设您需要常规网格上的某些内容,您可以使用简单的分区来存储数据。以下是一个例子:

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
中添加相应的值。您可以使用以下方法执行无缓冲添加:

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

结果是这样的:

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

整个操作在我的功率非常适中的机器上耗时6.4秒,耗时10万点,包括调用
plt.imshow
plt.colorbar
和运行前的垃圾收集

使用IPython中的
%%timeit
单元格魔术收集的计时


不管怎样,你的工作时间都不到450小时。即使您的坐标变换不是线性装箱,我希望您可以在合理的时间内运行,只要您将其正确矢量化。此外,多处理不太可能给您带来巨大的提升,因为它需要复制周围的数据。

假设您需要常规网格上的数据,您可以使用简单的分区来存储数据。以下是一个例子:

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
中添加相应的值。您可以使用以下方法执行无缓冲添加:

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

结果是这样的:

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

整个操作在我的功率非常适中的机器上耗时6.4秒,耗时10万点,包括调用
plt.imshow
plt.colorbar
和运行前的垃圾收集

使用IPython中的
%%timeit
单元格魔术收集的计时


不管怎样,你的工作时间都不到450小时。即使您的坐标变换不是线性装箱,我希望您可以在合理的时间内运行,只要您将其正确矢量化。此外,多处理不太可能给您带来巨大的提升,因为它需要复制周围的数据。

这在很大程度上取决于
convertPointPos2PixelPos
是否可以矢量化。在最坏的情况下,您将使用设计用于处理数组的方法进行迭代,而不是像什么是点?什么是数据?请发布MCVE。这在很大程度上取决于
convertPointPos2PixelPos
是否可以矢量化。在最坏的情况下,您将使用设计用于处理数组的方法进行迭代,而不是像什么是点?什么是数据?请发一张MCVE。