如何在numpy中将二维数组中的行切片归零?

时间:2017-12-12 03:27:15

标签: python arrays numpy

我有一个代表图像的numpy数组。我想将每列中某一行以下的所有索引清零(基于外部数据)。我似乎无法弄清楚如何切片/广播/安排数据来做这个“numpy方式”。

def first_nonzero(arr, axis, invalid_val=-1):
    mask = arr!=0
    return np.where(mask.any(axis=axis), mask.argmax(axis=axis), invalid_val)

# Find first non-zero pixels in a processed image
# Note, I might have my axes switched here... I'm not sure.
rows_to_zero = first_nonzero(processed_image, 0, processed_image.shape[1])

# zero out data in image below the rows found
# This is the part I'm stuck on.
image[:, :rows_to_zero, :] = 0  # How can I slice along an array of indexes?

# Or in plain python, I'm trying to do this:
for x in range(image.shape[0]):
    for y in range(rows_to_zero, image.shape[1]):
        image[x,y] = 0

1 个答案:

答案 0 :(得分:2)

创建一个利用broadcasting并分配 -

的模板
mask = rows_to_zero <= np.arange(image.shape[0])[:,None]
image[mask] = 0

或者使用反转掩码乘以:image *= ~mask

示例运行以展示掩码设置 -

In [56]: processed_image
Out[56]: 
array([[1, 0, 1, 0],
       [1, 0, 1, 1],
       [0, 1, 1, 0],
       [0, 1, 0, 1],
       [1, 1, 1, 1],
       [0, 1, 0, 1]])

In [57]: rows_to_zero
Out[57]: array([0, 2, 0, 1])

In [58]: rows_to_zero <= np.arange(processed_image.shape[0])[:,None]
Out[58]: 
array([[ True, False,  True, False],
       [ True, False,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True]], dtype=bool)

另外,对于每列设置,我认为你的意思是:

rows_to_zero = first_nonzero(processed_image, 0, processed_image.shape[0]-1)

如果你打算按行进行清零,那么每行的索引首先是非零索引,我们称之为idx。那么,那么做 -

mask = idx[:,None] <= np.arange(image.shape[1])
image[mask] = 0

示例运行 -

In [77]: processed_image
Out[77]: 
array([[1, 0, 1, 0],
       [1, 0, 1, 1],
       [0, 1, 1, 0],
       [0, 1, 0, 1],
       [1, 1, 1, 1],
       [0, 1, 0, 1]])

In [78]: idx = first_nonzero(processed_image, 1, processed_image.shape[1]-1)

In [79]: idx
Out[79]: array([0, 0, 1, 1, 0, 1])

In [80]: idx[:,None] <= np.arange(image.shape[1])
Out[80]: 
array([[ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [False,  True,  True,  True],
       [False,  True,  True,  True],
       [ True,  True,  True,  True],
       [False,  True,  True,  True]], dtype=bool)