在numpy 2D数组上-如何在N行变化时将每行的最后N个数组元素设置为零

avi*_*Che 1 python numpy vectorization

说,我有一个由20个元素组成的2D numpy数组,例如:

arr = np.array([[1, 2, 15, 7],[9, 11, 17, 19],[5, 7, 5, 8],[19, 4, 1, 45],[10, 7, 14, 8]])
Run Code Online (Sandbox Code Playgroud)

和一个额外的数组:

to_zero = np.array([0, 2, 1, 3, 2])
Run Code Online (Sandbox Code Playgroud)

现在,对于每一行,i我想使最后一个to_zero[i]元素等于零,因此最终我们将得到以下结果:

res = np.array([[1, 2, 15, 7],[9, 11, 0, 0],[5, 7, 5, 0],[19, 0, 0, 0],[10, 7, 0, 0]])
Run Code Online (Sandbox Code Playgroud)

我想在很大的数组上执行此操作。有什么方法可以向量化此操作,没有循环,也没有辅助数组吗?

Div*_*kar 5

使用broadcasted-comparison得到那些尾随的面具,然后屏蔽输入-

In [63]: r = np.arange(arr.shape[1])[::-1]

In [66]: mask = to_zero[:,None]>r

In [69]: mask # mask of trailing places to be reset in input
Out[69]: 
array([[False, False, False, False],
       [False, False,  True,  True],
       [False, False, False,  True],
       [False,  True,  True,  True],
       [False, False,  True,  True]])

In [67]: arr[mask] = 0

In [68]: arr
Out[68]: 
array([[ 1,  2, 15,  7],
       [ 9, 11,  0,  0],
       [ 5,  7,  5,  0],
       [19,  0,  0,  0],
       [10,  7,  0,  0]])
Run Code Online (Sandbox Code Playgroud)

替代获取r将与np.arange(arr.shape[1]-1,-1,-1)

通过元素乘法获得最终输出的替代方法:arr*~mask

或构建的翻转面罩翻转,比较,然后乘以-

In [75]: arr*(to_zero[:,None]<=np.arange(arr.shape[1]-1,-1,-1))
Out[75]: 
array([[ 1,  2, 15,  7],
       [ 9, 11,  0,  0],
       [ 5,  7,  5,  0],
       [19,  0,  0,  0],
       [10,  7,  0,  0]])
Run Code Online (Sandbox Code Playgroud)

对于大型阵列,请利用numexpr-

In [78]: import numexpr as ne

In [79]: ne.evaluate('arr*mask',{'mask':to_zero[:,None]<=np.arange(arr.shape[1]-1,-1,-1)})
Out[79]: 
array([[ 1,  2, 15,  7],
       [ 9, 11,  0,  0],
       [ 5,  7,  5,  0],
       [19,  0,  0,  0],
       [10,  7,  0,  0]])
Run Code Online (Sandbox Code Playgroud)

  • @aviyaChe基本上,您是在请求内置函数,可悲的是NumPy中没有任何函数。另外,我们正在构造一个掩码/布尔数组,它在unix系统上占据一个int数组的1/8。 (2认同)