我有一个numpy数组的零。具体来说,假设它是2x3x4:
x = np.zeros((2,3,4))
并假设我有一个2x3的随机整数数组,从0到3(x的第三维索引)。
>>> y = sp.stats.distributions.randint.rvs(0, 4, size=(2,3))
>>> y
[[2 1 0]
[3 2 0]]
如何有效地执行以下分配(编辑:不用于循环的东西,适用于x,具有任意数量的维度和每个维度中的任意数量的元素)?
>>> x[0,0,y[0,0]]=1
>>> x[0,1,y[0,1]]=1
>>> x[0,2,y[0,2]]=1
>>> x[1,0,y[1,0]]=1
>>> x[1,1,y[1,1]]=1
>>> x[1,2,y[1,2]]=1
>>> x
array([[[ 0., 0., 1., 0.],
[ 0., 1., 0., 0.],
[ 1., 0., 0., 0.]],
[[ 0., 0., 0., 1.],
[ 0., 0., 1., 0.],
[ 1., 0., 0., 0.]]])
谢谢, 詹姆斯
答案 0 :(得分:1)
目前,我只能想到“简单”版本,它涉及沿前两个维度展平。这段代码应该有效:
shape_last = x.shape[-1]
x.reshape((-1, shape_last))[np.arange(y.size), y.flatten()] = 1
这会产生(我随机生成的y
):
array([[[ 0., 0., 0., 1.],
[ 0., 0., 1., 0.],
[ 0., 1., 0., 0.]],
[[ 0., 1., 0., 0.],
[ 0., 0., 0., 1.],
[ 0., 1., 0., 0.]]])
关键是,如果使用多个numpy数组(advanced indexing)进行索引,numpy将使用索引对来索引数组。
当然,请确保x
和y
都是C顺序或F顺序 - 否则,对reshape
和flatten
的调用可能会给出不同的顺序
答案 1 :(得分:1)
使用numpy.meshgrid()创建索引数组,您可以使用它来索引原始数组和第三维数组的值数组。
import numpy as np
import scipy as sp
import scipy.stats.distributions
a = np.zeros((2,3,4))
z = sp.stats.distributions.randint.rvs(0, 4, size=(2,3))
xx, yy = np.meshgrid( np.arange(2), np.arange(3) )
a[ xx, yy, z[xx, yy] ] = 1
print a
为了清楚起见,我已将您的数组从x重命名为a,将索引数组从y重命名为z。
编辑: 4D示例:
a = np.zeros((2,3,4,5))
z = sp.stats.distributions.randint.rvs(0, 4, size=(2,3))
w = sp.stats.distributions.randint.rvs(0, 5, size=(2,3))
xx, yy = np.meshgrid( np.arange(2), np.arange(3) )
a[ xx, yy, z[xx, yy], w[xx, yy] ] = 1
答案 2 :(得分:0)
x = np.zeros((2,3,4))
y=np.array([[2, 1, 0],[3, 2, 0]]) # or y=sp.stats...
for i in range(2):
for j in range(3):
x[i,j,y[i,j]]=1
将产生预期的结果,IIRC。如果数组维度永远不会改变,请考虑用
替换两个for循环及其负担for j in range(3):
x[0,j,y[0,j]] = x[1,j,y[1,j]] = 1