如何创建一个零的 numpy N 维数组,只有一个元素等于 1?



有没有一种简短的单行方法来创建numpy数组(可能有多个维度(,该数组在某个位置有一个,而在所有其他位置为零?对于一维数组,可以执行以下操作来创建 k^{th} 位置为 1 的数组:

np.eye(1, N, k = k)

如何将其推广到更高维度的情况?

例如,如果您需要一个索引为 1 的 3x5 矩阵 (2, 3(,只需创建一个 1D 数组,然后重塑它:

M, N = 3, 5
i, j = 2, 3
np.eye(1, M * N, k=(i+1) * M + j).reshape(M, N)
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0.]])

知道每个多维 numpy 数组在内部表示为一维数组可能会有所帮助,并带有一些包装器逻辑来处理步幅和索引。这意味着这里的解决方案也可以通过适当的算术推广到任何维度。这是一个概括:

def make_nd_array_with(dims, index):
return (np.eye(1, 
np.prod(dims), 
k=(((np.array(index[:-1]) + 1) * dims[:-1]).sum() + index[-1]))
.reshape(*dims))
make_nd_array_with((M,N), (i,j))
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0.]])

请注意,这解决了您希望在一行中执行此操作的约束,但通常规范的解决方案是创建一个零数组并设置单个值,如注释和其他答案所述。

arr = np.zeros(M, N)
arr[i, j] = 1

与其使用eyereshape,只编写一个调用zeros并设置所需元素的函数要清晰得多

def mostly_zeros(shape, nonzero_position, dtype=float, nonzero_element=1):
retval = numpy.zeros(shape, dtype=dtype)
retval[nonzero_index] = nonzero_element
return retval

然后,您可以调用mostly_zeros(shape=(4, 5), nonzero_position=(2, 2))来获取一个几乎为零的形状(4, 5)数组,并在位置(2, 2)处具有1.0。这将比eye少得多的维护头痛。


或者,您可以编写一个设置项目并返回数组的函数:

def chainable_setitem(obj, index, val):
obj[index] = val
return obj

然后你可以做chainable_setitem(numpy.zeros((4, 5)), (2, 2), 1)得到一个 4x5 数组,在其他地方的位置 2、2 和零处有一个 1.0。

既然你要求单行:

np.bincount([np.ravel_multi_index(pos,shp)],None,np.prod(shp)).reshape(shp)

shp = 3,4
pos = 1,2
np.bincount([np.ravel_multi_index(pos,shp)],None,np.prod(shp)).reshape(shp)
# array([[0, 0, 0, 0],
#        [0, 0, 1, 0],
#        [0, 0, 0, 0]])

诚然,这对于 1D 来说要好得多,因为它简化了

np.bincount([pos],None,length)

比 nD