有没有一种简短的单行方法来创建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
与其使用eye
或reshape
,只编写一个调用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