将每行的最后一个非零元素设置为零-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
I want to change the last non-zero of each row to 0
A = array([[1, 2, 3,0], [5,6,0,0] , [8,0,0,0]])
如何为任何n * m numpy数组编写代码? 谢谢,S;-)
how to write the code for any n*m numpy array? Thanks, S ;-)
推荐答案
方法1
基于cumsum
和argmax
的一种方法-
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
的代码,希望效率更高-
One more based on argmax
and hopefully more efficient -
A[np.arange(A.shape[0]),A.shape[1] - 1 - (A[:,::-1]!=0).argmax(1)] = 0
说明
argmax
的用途之一是获取max
元素在数组中沿轴的 first 出现的ID.在第一种方法中,我们沿行获取总和,并获取第一个最大ID,该ID代表最后一个非零元素.这是因为剩余元素上的cumsum
不会在最后一个非零元素之后增加总和值.
One of the uses of argmax
is to get ID of the first occurence of the max
element along an axis in an array . In the first approach we get the cumsum along the rows and get the first max ID, which represents the last non-zero elem. This is because cumsum
on the leftover elements won't increase the sum value after that last non-zero element.
让我们以更详细的方式重新运行该案例-
Let's re-run that case in a bit more detailed manner -
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
中设置适当的元素.
Finally, we use fancy-indexing
to use those as the column indices to set appropriate elements in A
.
在第二种方法中,当我们在布尔数组上使用argmax
时,我们只得到了True
的第一次出现,我们在输入数组的行翻转版本中使用了它.这样,我们将拥有原始顺序中的最后一个非零元素.剩下的想法是一样的.
In the second approach, when we use argmax
on the boolean array, we simply got the first occurence of True
, which we used on a row-flipped version of the input array. As such, we would have the last non-zero elem in the original order. Rest of the idea there, is the same.
这篇关于将每行的最后一个非零元素设置为零-NumPy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!