有没有办法优化这个NumPy索引重新分配?

huangapple go评论73阅读模式
英文:

Any way to optimize this NumPy indexed reassignation?

问题

我试图实现的基本上是HDR:从每个曝光级别中获取最强烈的像素,并替换主图像中相应的像素(如果它已经是最强烈的则保持不变)。

我主要是想改进for循环,因为它在处理大型数组时是主要的瓶颈。

hdr_data = np.array([main_scan.data, lower_scan.data, higher_scan.data])

maximum_intensities = hdr_data.max(axis=-1)
frame_indices = np.argmax(maximum_intensities, axis=0)

for i, index in enumerate(frame_indices):
	main_scan.data[i] = hdr_data[index, i, :]

main_scanlower_scanhigher_scan 的形状是 X*Y,而 hdr_data 的形状是 3*X*Y

英文:

What I'm trying to achieve is basically HDR: grab the most intense pixel out of each exposure level and replace the corresponding pixel in the main image (or keep as-is if it's already the most intense).

I'm mainly looking to improve the for loop, as it's the main bottleneck when processing large arrays.

hdr_data = np.array([main_scan.data, lower_scan.data, higher_scan.data])

maximum_intensities = hdr_data.max(axis=-1)
frame_indices = np.argmax(maximum_intensities, axis=0)

for i, index in enumerate(frame_indices):
	main_scan.data[i] = hdr_data[index, i, :]

main_scan, lower_scan and higher_scan are in X*Y shapes, and hdr_data is in 3*X*Y shape

答案1

得分: 1

hdr_data   # (3,x,y) 形状
maximum_intensities    # (3,x) 形状
frame_indices # (x,) 形状,值为 0,1,2

iterative:

    for i, index in enumerate(frame_indices):
        main_scan.data[i] = hdr_data[index, i, :]

try:

    max_data = hdr_data[np.arange(x)[:,None], frame_indices] # (x,y)

`np.take_along_axis` 也可以做到这一点参见其文档

test

    In [340]: arr = np.random.randint(0,10,(3,10,4))
    
    In [341]: idx=np.argmax(arr.max(axis=-1), axis=0)
    
    In [342]: idx
    Out[342]: array([0, 0, 0, 0, 1, 0, 0, 2, 0, 0], dtype=int64)
    
    In [343]: arr[np.arange(10),idx,:]
    ---------------------------------------------------------------------------
    IndexError                                Traceback (most recent call last)
    Cell In[343], line 1
    ----> 1 arr[np.arange(10),idx,:]
    
    IndexError: index 3 is out of bounds for axis 0 with size 3

oops颠倒索引顺序
    
    In [344]: arr[idx,np.arange(10),:]
    Out[344]: 
    array([[4, 2, 4, 9],
           [1, 9, 1, 4],
           [7, 0, 1, 4],
           [1, 6, 8, 9],
           [5, 9, 5, 1],
           [8, 5, 0, 7],
           [7, 1, 1, 5],
           [7, 9, 8, 2],
           [2, 6, 4, 9],
           [7, 4, 1, 9]])
英文:
hdr_data   # (3,x,y) shape
maximum_intensities    # (3,x) shape
frame_indices # (x,) shape, values 0,1,2

iterative:

for i, index in enumerate(frame_indices):
    main_scan.data[i] = hdr_data[index, i, :]

try:

max_data = hdr_data[np.arange(x)[:,None], frame_indices] # (x,y)

np.take_along_axis can also do this; see its docs

test

In [340]: arr = np.random.randint(0,10,(3,10,4))

In [341]: idx=np.argmax(arr.max(axis=-1), axis=0)

In [342]: idx
Out[342]: array([0, 0, 0, 0, 1, 0, 0, 2, 0, 0], dtype=int64)

In [343]: arr[np.arange(10),idx,:]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[343], line 1
----> 1 arr[np.arange(10),idx,:]

IndexError: index 3 is out of bounds for axis 0 with size 3

oops, reverse the index order:

In [344]: arr[idx,np.arange(10),:]
Out[344]: 
array([[4, 2, 4, 9],
       [1, 9, 1, 4],
       [7, 0, 1, 4],
       [1, 6, 8, 9],
       [5, 9, 5, 1],
       [8, 5, 0, 7],
       [7, 1, 1, 5],
       [7, 9, 8, 2],
       [2, 6, 4, 9],
       [7, 4, 1, 9]])

huangapple
  • 本文由 发表于 2023年6月13日 06:00:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76460582.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定