代码之家  ›  专栏  ›  技术社区  ›  sixtytrees

在numpy数组中填充圆内的1,其他地方填充零

  •  1
  • sixtytrees  · 技术社区  · 1 年前

    我试图模仿一个用1填充的圆,数组的其余部分用0填充 numpy 大堆这与图形与圆重叠的数值计算有关。目前,我最多可以按元素进行(这很慢):

    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倍以上,我们应该承认这一点。

    2 回复  |  直到 1 年前
        1
  •  5
  •   Chrysophylaxs    1 年前

    你也可以使用广播,或者在某种程度上等效 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)
    
        2
  •  3
  •   jmd_dk    1 年前

    可以使用布尔掩码。关键是要有一种方法来创建 h w 同时,下面调用 X Y 。查看 meshgrid docs 详细信息。

    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