簡體   English   中英

將每行的最后一個非零元素設置為零 - NumPy

[英]Set last non-zero element of each row to zero - NumPy

我有一個數組 A:

A = array([[1, 2, 3,4], [5,6,7,0] , [8,9,0,0]])

我想將每行的最后一個非零更改為 0

A = array([[1, 2, 3,0], [5,6,0,0] , [8,0,0,0]])

如何為任何 n*m numpy 數組編寫代碼? 謝謝,S ;-)

方法#1

一種基於cumsumargmax -

A[np.arange(A.shape[0]),(A!=0).cumsum(1).argmax(1)] = 0

樣品運行 -

In [59]: A
Out[59]: 
array([[2, 0, 3, 4],
       [5, 6, 7, 0],
       [8, 9, 0, 0]])

In [60]: A[np.arange(A.shape[0]),(A!=0).cumsum(1).argmax(1)] = 0

In [61]: A
Out[61]: 
array([[2, 0, 3, 0],
       [5, 6, 0, 0],
       [8, 0, 0, 0]])

方法#2

另一個基於argmax並且希望更高效 -

A[np.arange(A.shape[0]),A.shape[1] - 1 - (A[:,::-1]!=0).argmax(1)] = 0

解釋

argmax一個用途是獲取數組中沿軸的max元素第一次出現的ID。 在第一種方法中,我們沿行獲取 cumsum 並獲取第一個最大 ID,它表示最后一個非零元素。 這是因為剩余元素上的cumsum不會增加最后一個非零元素之后的總和值。

讓我們以更詳細的方式重新運行該案例 -

In [105]: A
Out[105]: 
array([[2, 0, 3, 4],
       [5, 6, 7, 0],
       [8, 9, 0, 0]])

In [106]: (A!=0)
Out[106]: 
array([[ True, False,  True,  True],
       [ True,  True,  True, False],
       [ True,  True, False, False]], dtype=bool)

In [107]: (A!=0).cumsum(1)
Out[107]: 
array([[1, 1, 2, 3],
       [1, 2, 3, 3],
       [1, 2, 2, 2]])

In [108]: (A!=0).cumsum(1).argmax(1)
Out[108]: array([3, 2, 1])

最后,我們使用fancy-indexing將它們用作列索引以在A設置適當的元素。

在第二種方法中,當我們在布爾數組上使用argmax時,我們只是得到了第一次出現的True ,我們在輸入數組的行翻轉版本中使用了它。 因此,我們將擁有原始順序中的最后一個非零元素。 其余的想法是一樣的。

一種方法是使用您想要的行和列索引顯式地形成數組:

A = np.array([[1, 2, 3,4], [5,6,7,0] , [8,9,0,0]])
row_inds = np.arange(A.shape[0])
col_inds = np.arange(A.shape[1])
nonzero_col_inds = (A > 0) * col_inds
max_nonzero_col_inds = np.max(nonzero_col_inds, 1)
A[row_inds, max_nonzero_col_inds] = 0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM