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

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

Any way to optimize this NumPy indexed reassignation?

问题

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

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

  1. hdr_data = np.array([main_scan.data, lower_scan.data, higher_scan.data])
  2. maximum_intensities = hdr_data.max(axis=-1)
  3. frame_indices = np.argmax(maximum_intensities, axis=0)
  4. for i, index in enumerate(frame_indices):
  5. 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.

  1. hdr_data = np.array([main_scan.data, lower_scan.data, higher_scan.data])
  2. maximum_intensities = hdr_data.max(axis=-1)
  3. frame_indices = np.argmax(maximum_intensities, axis=0)
  4. for i, index in enumerate(frame_indices):
  5. 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

  1. hdr_data # (3,x,y) 形状
  2. maximum_intensities # (3,x) 形状
  3. frame_indices # (x,) 形状,值为 0,1,2
  4. iterative:
  5. for i, index in enumerate(frame_indices):
  6. main_scan.data[i] = hdr_data[index, i, :]
  7. try:
  8. max_data = hdr_data[np.arange(x)[:,None], frame_indices] # (x,y)
  9. `np.take_along_axis` 也可以做到这一点参见其文档
  10. test
  11. In [340]: arr = np.random.randint(0,10,(3,10,4))
  12. In [341]: idx=np.argmax(arr.max(axis=-1), axis=0)
  13. In [342]: idx
  14. Out[342]: array([0, 0, 0, 0, 1, 0, 0, 2, 0, 0], dtype=int64)
  15. In [343]: arr[np.arange(10),idx,:]
  16. ---------------------------------------------------------------------------
  17. IndexError Traceback (most recent call last)
  18. Cell In[343], line 1
  19. ----> 1 arr[np.arange(10),idx,:]
  20. IndexError: index 3 is out of bounds for axis 0 with size 3
  21. oops颠倒索引顺序
  22. In [344]: arr[idx,np.arange(10),:]
  23. Out[344]:
  24. array([[4, 2, 4, 9],
  25. [1, 9, 1, 4],
  26. [7, 0, 1, 4],
  27. [1, 6, 8, 9],
  28. [5, 9, 5, 1],
  29. [8, 5, 0, 7],
  30. [7, 1, 1, 5],
  31. [7, 9, 8, 2],
  32. [2, 6, 4, 9],
  33. [7, 4, 1, 9]])
英文:
  1. hdr_data # (3,x,y) shape
  2. maximum_intensities # (3,x) shape
  3. frame_indices # (x,) shape, values 0,1,2

iterative:

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

try:

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

np.take_along_axis can also do this; see its docs

test

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

oops, reverse the index order:

  1. In [344]: arr[idx,np.arange(10),:]
  2. Out[344]:
  3. array([[4, 2, 4, 9],
  4. [1, 9, 1, 4],
  5. [7, 0, 1, 4],
  6. [1, 6, 8, 9],
  7. [5, 9, 5, 1],
  8. [8, 5, 0, 7],
  9. [7, 1, 1, 5],
  10. [7, 9, 8, 2],
  11. [2, 6, 4, 9],
  12. [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:

确定