简体   繁体   English

列和行范围内的 Numpy 数组操作

[英]Numpy array manipulation within range of columns and rows

I have a numpy boolean 2D array that represents a grayscale image which is essentially an unfilled shape (triangle, square, circle) consisting of True for white pixels, and False for black pixels.我有一个 numpy 布尔 2D 数组,它表示一个灰度图像,它本质上是一个未填充的形状(三角形、正方形、圆形),由白色像素的True和黑色像素的False组成。 I would like to add a black fill by modifying the white pixels to black pixels.我想通过将白色像素修改为黑色像素来添加黑色填充。

array([[True, True, True, False, False, False, False, False, True, True, True],
       [True, True, True, False,  True,  True,  True, False, True, True, True],
       [True, True, True, False,  True,  True,  True, False, True, True, True],
       [True, True, True, False,  True,  True,  True, False, True, True, True],
       [True, True, True, False, False, False, False, False, True, True, True]])

(The 9 True values in a square in the middle of this array should become False .) (此数组中间正方形中的 9 个True值应变为False 。)

Is there a numpy slice method that will make this easy/fast?是否有一种 numpy slice 方法可以使这变得简单/快速? Something that I can modify all True s anytime there's a False followed by a True until the next instance of a False ?我可以在任何时候修改所有True的东西,有一个False然后是一个True直到下一个False实例?

Here one idea that's easy to implement and should perform reasonably quickly.这是一个易于实施并且应该相当快地执行的想法。

I'll use 0s and 1s so it's a little clearer to look at.我将使用 0 和 1,这样看起来会更清晰一些。

Here's the starting array:这是起始数组:

>>> a
array([[1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1],
       [1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1],
       [1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1],
       [1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1]])

Accumulate left-to-right using np.logical_and.accumulate , flip left-to-right, do the same again, flip back, and the "or" the two arrays together:使用np.logical_and.accumulate从左到右np.logical_and.accumulate ,从左到右翻转,再次执行相同操作,再翻转回来,然后将两个数组的“或”组合在一起:

>>> andacc = np.logical_and.accumulate
>>> (andacc(a, axis=1) | andacc(a[:, ::-1], axis=1)[:, ::-1]).astype(int)
array([[1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1]])

(Leave out .astype(int) to keep a boolean array instead of 0s and 1s.) (省略.astype(int)以保留布尔数组而不是 0 和 1。)

Here's a triangle:这是一个三角形:

>>> b
array([[1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1],
       [1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1],
       [1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1],
       [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0]])

>>> (andacc(b, axis=1) | andacc(b[:, ::-1], axis=1)[:, ::-1]).astype(int)
array([[1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1],
       [1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1],
       [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

Based on your logic, you can replace all values between the first False and the last False with False:根据您的逻辑,您可以用 False 替换第一个 False 和最后一个 False 之间的所有值:

def mutate(A):
    ind = np.where(~A)[0]
    if len(ind) != 0:
        A[ind.min():ind.max()] = False
    return A


np.apply_along_axis(mutate, 1, arr)

# array([[ True,  True,  True, False, False, False, False, False,  True,
#          True,  True],
#        [ True,  True,  True, False, False, False, False, False,  True,
#          True,  True],
#        [ True,  True,  True, False, False, False, False, False,  True,
#          True,  True],
#        [ True,  True,  True, False, False, False, False, False,  True,
#          True,  True],
#        [ True,  True,  True, False, False, False, False, False,  True,
#          True,  True]], dtype=bool)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM