2017-12-12 26 views
2

私は画像を表す配列があります。私は各列の特定の行の下にあるすべてのインデックスをゼロにしたい(外部データに基づいて)。私はこれを行うためのデータをスライス/ブロードキャスト/アレンジする方法を理解していないようです。numpyで2次元配列の行スライスをゼロにする方法は?

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 

答えて

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) 
+0

おかげで、これはそんなに助けました!そして、あなたは正しかった、私はfirst_nonzero(image、0、image.shape [0] -1) – Jordan

関連する問題