2013-06-24 46 views
2

我下面的代碼,這似乎是性能瓶頸:用Numpy從點列表創建圖像,如何加速?

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

如果您將您的二維座標爲target_map成扁平狀的指數納入使用np.ravel_multi_index它,你可以使用np.uniquenp.bincount加快速度頗有幾分:

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倍的速度增加。

+0

這太好了。我仍在試圖弄清楚發生了什麼,但是現在的性能已經達到了「足夠快」的水平。 – Harriv