如何创建一个numpy的N维数组,其中所有元素都为0,只有一个元素等于1?

3

有没有一种简单的方法来创建一个numpy数组(可能有多个维度),其中某个位置为1,其他位置为0?对于一维数组,可以使用以下方法在第k个位置创建一个具有1的数组:

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

这如何推广到更高维的情况?


如果数组不是一维的,那么哪个是1,哪个是0呢?1是否唯一出现在第一个位置,或者每个最后一维数组的第一个位置?请给出示例。 - azro
以一种“可爱”的方式? - Chris
@azro 类似这样:np.array([[0, 0, 1], [0, 0, 0]]) - 唯一的非零元素位于[0, 2]。通常情况下,如果数组是N维的,除了某些[i_1, i_2, \ldots, i_n]位置为1外,所有位置都为0。 - spiridon_the_sun_rotator
3个回答

3
例如,如果您需要一个3x5矩阵,并且在索引(2,3)处需要1,则只需创建一个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数组实际上都是以1D数组的形式进行内部表示的,同时还有一些包装逻辑来处理步长和索引。这意味着这里的解决方案也可以通过适当的算术运算推广到任何维度。以下是一个泛化版本:

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

请注意,这假定按行主序计算索引。 - cs95

3
与其使用 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,其他位置都是0。


这显然是标准答案,op添加了一个限制条件要求在一行内完成,而我的答案解决了这个问题。但这就是正确的答案。 - cs95

1
"由于你要求一行代码: "
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]])

诚然,在一维情况下,这样做会更好,因为它可以简化为

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

感谢nD。

对于一维情况,使用 np.eye 会更好:np.eye(<N>)[<pos>] - z1ne2wo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接