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

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

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

问题

以下是代码的翻译部分:

我正在尝试在`numpy`数组中模拟一个用1填充的圆形其余部分用0填充这与计算图形与圆的重叠的数值计算有关目前我最多只能逐元素执行这很慢):

import numpy as np
from my_magic_constants import center, radius

c1 = np.zeros((center*2, center*2))
for h in range(center*2):
    for w in range(center*2):
        if (center-h)**2 + (center-w)**2 < radius**2:
            c1[h,w] = 1

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


更新

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

import numpy as np
from time import time

eps = 1e-10
center = 8119
square_half_size = 5741
square = np.zeros((center*2, center*2))
square[center-square_half_size:center+square_half_size, center-square_half_size:center+square_half_size] = 1

def iou(c):
    overlap = c * square
    union = (c + square).clip(0,1)
    return np.sum(overlap)/(np.sum(union) + eps)

best_iou = 0

for radius in range(center - int(square_half_size * 1.093), center):
    t1 = time()
    c1 = np.zeros((center*2, center*2))
    for h in range(center*2):
        for w in range(center*2):
            if (center-h)**2 + (center-w)**2 < radius**2:
                c1[h,w] = 1

    current_iou = iou(c1)
    if current_iou > best_iou:
        best_iou = current_iou
        # print(i, best_iou)
    t = time() - t1

    print(t)
    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):

import numpy as np
from my_magic_constants import center, radius

c1 = np.zeros((center*2, center*2))
for h in range(center*2):
	for w in range(center*2):
		if (center-h)**2 + (center-w)**2 < radius**2:
			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

import numpy as np
from time import time

eps = 1e-10
center = 8119
square_half_size = 5741
square = np.zeros((center*2, center*2))
square[center-square_half_size:center+square_half_size, center-square_half_size:center+square_half_size] = 1


def iou(c):
    overlap = c * square
    union = (c + square).clip(0,1)
    return np.sum(overlap)/(np.sum(union) + eps)


best_iou = 0

for radius in range(center - int(square_half_size * 1.093), center):
    t1 = time()
    c1 = np.zeros((center*2, center*2))
    for h in range(center*2):
        for w in range(center*2):
            if (center-h)**2 + (center-w)**2 < radius**2:
                c1[h,w] = 1

    current_iou = iou(c1)
    if current_iou > best_iou:
        best_iou = current_iou
        # print(i, best_iou)
    t = time() - t1

    print(t)
    break

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

答案1

得分: 5

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

import numpy as np
center, radius = 10, 5

arr = np.arange(-center, center) ** 2
out = np.add.outer(arr, arr) < radius ** 2
# or: arr[:, None] + arr[None, :] < radius ** 2

# Optionally convert dtype if you don't like bool:
out = out.astype(float)
英文:

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

import numpy as np
center, radius = 10, 5

arr = np.arange(-center, center) ** 2
out = np.add.outer(arr, arr) &lt; radius ** 2
# or: arr[:, None] + arr[None, :] &lt; radius ** 2

# Optionally convert dtype if you don&#39;t like bool:
out = out.astype(float)

答案2

得分: 3

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

import numpy as np
center, radius = 10, 5

c1 = np.zeros((center*2, center*2))
for h in range(center*2):
    for w in range(center*2):
        if (center-h)**2 + (center-w)**2 < radius**2:
            c1[h,w] = 1
print(c1)

c2 = np.zeros((center*2, center*2))
x = np.arange(c2.shape[0])
X, Y = np.meshgrid(x, x)
c2[(X - center)**2 + (Y - center)**2 < radius**2] = 1
print(c2)

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.

import numpy as np
center, radius = 10, 5

c1 = np.zeros((center*2, center*2))
for h in range(center*2):
    for w in range(center*2):
        if (center-h)**2 + (center-w)**2 &lt; radius**2:
            c1[h,w] = 1
print(c1)

c2 = np.zeros((center*2, center*2))
x = np.arange(c2.shape[0])
X, Y = np.meshgrid(x, x)
c2[(X - center)**2 + (Y - center)**2 &lt; radius**2] = 1
print(c2)

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:

确定