如何根据索引和值有效地更新 np 数组?

How to efficiently update np array depending on index and value?

我有一张太阳的图像,我找到了中心和半径,现在我想以不同的方式处理像素(如果它们在磁盘内部或外部)。理想的解决方案是对处理函数的参数进行插值,以便从磁盘平滑过渡到后台。

这是我现在正在做的事情:

for index,value in np.ndenumerate(sun_img):
    if distance.euclidean(index,center) > radius:
        sun_img[index] = processing_function(index,value)

像这样它可以工作,但是计算图像需要很长时间。我相信有一种更有效的方法可以做到这一点。你会如何解决这个问题?

图片形状在(1000, 1000)左右 Processing_function 现在基本上什么都没做:value += 1

该函数应该类似于非线性 "step function",半径为 0.0,之后为 1.0 5px。类似于:_______/''''''''''''''''''''' 乘以像素值。坡度应在半径值上。我想这样做是为了增强突起

这是一种利用 NumPy broadcasting -

的矢量化方法
m,n = sun_img.shape  
I,J = np.ogrid[:m,:n]      
sq_dist = (I - center[0])**2 + (J - center[1])**2
valid_mask = sq_dist > radius**2

现在,对于仅将 1 添加到由 IF-conditional 定义的有效位置的 processing_function,执行 -

sun_img[valid_mask] += 1

如果您需要使用 processing_function 实现需要这些行、列索引的自定义操作,请使用 np.where 获取这些索引,然后遍历有效元素,就像这样 -

r,c = np.where(valid_mask)
for index in zip(r,c):
    sun_img[index] = processing_function(index,sun_img[r,c])

如果您有很多这样的有效位置,那么计算 r,c 可能会使速度变慢。在那种情况下,直接使用 mask,像这样 -

for index,value in np.ndenumerate(sun_img):
    if valid_mask[index]:
        sun_img[index] = processing_function(index,value)

与原始代码相比,好处是我们在进入循环之前预先计算了条件值。最好的方法还是矢量化 processing_function 本身,以便它可以处理更大的数据块,但这取决于它的实现。