使用Numpy从点列表创建图像,如何加速?

时间:2013-06-24 21:46:41

标签: optimization numpy enumeration

我遵循了似乎是性能瓶颈的代码:

for x, y, intensity in myarr:
  target_map[x, y] = target_map[x,y] + intensity

对于具有可变强度的相同坐标,有多个坐标。

数据类型:

> print myarr.shape, myarr.dtype
(219929, 3) uint32

> print target_map.shape, target_map.dtype
(150, 200) uint32

除了用C语言编写之外,有没有办法优化这个循环?

这似乎是一个相关的问题,我怎么能得不到接受的答案为我工作:How to convert python list of points to numpy image array?

我收到以下错误消息:

Traceback (most recent call last):
  File "<pyshell#38>", line 1, in <module>
    image[coordinates] = 1
IndexError: too many indices for array

1 个答案:

答案 0 :(得分:1)

如果您使用target_map将2D坐标转换为np.ravel_multi_index成平面索引,则可以使用np.uniquenp.bincount来加快速度:< / p>

def vec_intensity(my_arr, target_map) :
    flat_coords = np.ravel_multi_index((my_arr[:, 0], my_arr[:, 1]),
                                       dims=target_map.shape)
    unique_, idx = np.unique(flat_coords, return_inverse=True)
    sum_ = np.bincount(idx, weights=my_arr[:, 2])
    target_map.ravel()[unique_] += sum_
    return target_map

def intensity(my_arr, target_map) :
    for x, y, intensity in myarr:
        target_map[x, y] += intensity
    return target_map

#sample data set
rows, cols = 150, 200
items = 219929
myarr = np.empty((items, 3), dtype=np.uint32)
myarr[:, 0] = np.random.randint(rows, size=(items,))
myarr[:, 1] = np.random.randint(cols, size=(items,))
myarr[:, 2] = np.random.randint(100, size=(items,))

现在:

In [6]: %timeit target_map_1 = np.zeros((rows, cols), dtype=np.uint32); target_map_1 = vec_intensity(myarr, target_map_1)
10 loops, best of 3: 53.1 ms per loop

In [7]: %timeit target_map_2 = np.zeros((rows, cols), dtype=np.uint32); target_map_2 = intensity(myarr, target_map_2)
1 loops, best of 3: 934 ms per loop

In [8]: np.all(target_map_1 == target_map_2)
Out[8]: True

速度几乎提高了20倍。