[英]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.