用numpy数组在圆内填充1,圆外填充0。

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

Fill a numpy array with ones within a circle, zeros elsewhere

问题

以下是代码的翻译部分:

  1. 我正在尝试在`numpy`数组中模拟一个用1填充的圆形其余部分用0填充这与计算图形与圆的重叠的数值计算有关目前我最多只能逐元素执行这很慢):
  2. import numpy as np
  3. from my_magic_constants import center, radius
  4. c1 = np.zeros((center*2, center*2))
  5. for h in range(center*2):
  6. for w in range(center*2):
  7. if (center-h)**2 + (center-w)**2 < radius**2:
  8. c1[h,w] = 1

更有效的初始化numpy数组中的圆的方式是什么?


更新

我只检查了最早的答案的加速效果。如果有人想要进行计时基准测试,这里是代码:

  1. import numpy as np
  2. from time import time
  3. eps = 1e-10
  4. center = 8119
  5. square_half_size = 5741
  6. square = np.zeros((center*2, center*2))
  7. square[center-square_half_size:center+square_half_size, center-square_half_size:center+square_half_size] = 1
  8. def iou(c):
  9. overlap = c * square
  10. union = (c + square).clip(0,1)
  11. return np.sum(overlap)/(np.sum(union) + eps)
  12. best_iou = 0
  13. for radius in range(center - int(square_half_size * 1.093), center):
  14. t1 = time()
  15. c1 = np.zeros((center*2, center*2))
  16. for h in range(center*2):
  17. for w in range(center*2):
  18. if (center-h)**2 + (center-w)**2 < radius**2:
  19. c1[h,w] = 1
  20. current_iou = iou(c1)
  21. if current_iou > best_iou:
  22. best_iou = current_iou
  23. # print(i, best_iou)
  24. t = time() - t1
  25. print(t)
  26. break

如果有后续答案的速度快10倍以上,我们应该予以承认。

英文:

I am trying to imitate a circle filled with ones and the rest of the array filled with zeros in a numpy array. This has something to do with a numerical computation of the overlap of a figure with circles. For now at best I can do it elementwise (which is slow):

  1. import numpy as np
  2. from my_magic_constants import center, radius
  3. c1 = np.zeros((center*2, center*2))
  4. for h in range(center*2):
  5. for w in range(center*2):
  6. if (center-h)**2 + (center-w)**2 < radius**2:
  7. c1[h,w] = 1

What is the more efficient way to initialize a circle in a numpy array?


Update

I have only checked the acceleration by the earliest answer. If someone wants to benchmark timings, here is the code

  1. import numpy as np
  2. from time import time
  3. eps = 1e-10
  4. center = 8119
  5. square_half_size = 5741
  6. square = np.zeros((center*2, center*2))
  7. square[center-square_half_size:center+square_half_size, center-square_half_size:center+square_half_size] = 1
  8. def iou(c):
  9. overlap = c * square
  10. union = (c + square).clip(0,1)
  11. return np.sum(overlap)/(np.sum(union) + eps)
  12. best_iou = 0
  13. for radius in range(center - int(square_half_size * 1.093), center):
  14. t1 = time()
  15. c1 = np.zeros((center*2, center*2))
  16. for h in range(center*2):
  17. for w in range(center*2):
  18. if (center-h)**2 + (center-w)**2 < radius**2:
  19. c1[h,w] = 1
  20. current_iou = iou(c1)
  21. if current_iou > best_iou:
  22. best_iou = current_iou
  23. # print(i, best_iou)
  24. t = time() - t1
  25. print(t)
  26. break

If some later answer is 10+ times faster, we should acknowledge that.

答案1

得分: 5

你也可以使用广播,或者类似的 np.add.outer

  1. import numpy as np
  2. center, radius = 10, 5
  3. arr = np.arange(-center, center) ** 2
  4. out = np.add.outer(arr, arr) < radius ** 2
  5. # or: arr[:, None] + arr[None, :] < radius ** 2
  6. # Optionally convert dtype if you don't like bool:
  7. out = out.astype(float)
英文:

You can also use broadcasting, or somewhat equivalently np.add.outer:

  1. import numpy as np
  2. center, radius = 10, 5
  3. arr = np.arange(-center, center) ** 2
  4. out = np.add.outer(arr, arr) &lt; radius ** 2
  5. # or: arr[:, None] + arr[None, :] &lt; radius ** 2
  6. # Optionally convert dtype if you don&#39;t like bool:
  7. out = out.astype(float)

答案2

得分: 3

你可以使用布尔掩码。关键是要找到一种同时创建所有 hw 的方法,下面称为 XY。详细信息请查看网格文档

  1. import numpy as np
  2. center, radius = 10, 5
  3. c1 = np.zeros((center*2, center*2))
  4. for h in range(center*2):
  5. for w in range(center*2):
  6. if (center-h)**2 + (center-w)**2 < radius**2:
  7. c1[h,w] = 1
  8. print(c1)
  9. c2 = np.zeros((center*2, center*2))
  10. x = np.arange(c2.shape[0])
  11. X, Y = np.meshgrid(x, x)
  12. c2[(X - center)**2 + (Y - center)**2 < radius**2] = 1
  13. print(c2)
  14. print((c1 == c2).all()) # True
英文:

You can use a Boolean mask. The key is to have a way to create all h and w at the same time, below called X and Y. Check out the meshgrid docs for details.

  1. import numpy as np
  2. center, radius = 10, 5
  3. c1 = np.zeros((center*2, center*2))
  4. for h in range(center*2):
  5. for w in range(center*2):
  6. if (center-h)**2 + (center-w)**2 &lt; radius**2:
  7. c1[h,w] = 1
  8. print(c1)
  9. c2 = np.zeros((center*2, center*2))
  10. x = np.arange(c2.shape[0])
  11. X, Y = np.meshgrid(x, x)
  12. c2[(X - center)**2 + (Y - center)**2 &lt; radius**2] = 1
  13. print(c2)
  14. print((c1 == c2).all()) # True

huangapple
  • 本文由 发表于 2023年5月14日 03:24:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76244519.html
匿名

发表评论

匿名网友

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

确定