Python 具有高级混合索引的Numpy子数组分配 原始问题

Python 具有高级混合索引的Numpy子数组分配 原始问题,python,arrays,numpy,indexing,Python,Arrays,Numpy,Indexing,当我尝试分配数组的某些元素时,会收到一条非常奇怪的错误消息。我使用的是一个切片和一组索引的组合。请参见下面的简单示例 import scipy as sp a = sp.zeros((3, 4, 5)) b = sp.ones((4, 5)) I = sp.array([0, 1, 3]) b[:, I] = a[0, :, I] 此代码引发以下ValueError: ValueError:形状不匹配:形状(3,4)的值数组无法广播到形状(3,4)的索引结果 -- 跟进 结合使

当我尝试分配数组的某些元素时,会收到一条非常奇怪的错误消息。我使用的是一个切片和一组索引的组合。请参见下面的简单示例

 import scipy as sp

 a = sp.zeros((3, 4, 5))
 b = sp.ones((4, 5))

 I = sp.array([0, 1, 3])

 b[:, I] = a[0, :, I]
此代码引发以下
ValueError

ValueError:形状不匹配:形状(3,4)的值数组无法广播到形状(3,4)的索引结果

--

跟进 结合使用slice和seq时要小心。整数的数目。正如github上指出的:

x = rand(3, 5, 7)

print(x[0, :, [0,1]].shape)
# (2, 5)

print(x[0][:, [0,1]].shape)
# (5, 2)

这就是numpy的工作原理,但是x[0][:,I]与x[0,:,I]不同,这让人有点困惑。因为这是我想要的行为,所以我选择在代码中使用x[0][:,I]。

在这里,我得到了索引为
[0,1,4]
的错误:

IndexError: index 4 is out of bounds for axis 2 with size 4
它表示值
4
被用作索引,而大小4表示最大索引为3

编辑:现在您将其更改为
[0,1,3]
,在这里运行良好

编辑:对于您当前的代码,我得到了相同的错误,但当我打印阵列本身时,它们有一个横向形状:

print b[:, I]
print a[0, :, I]

[[ 1.  1.  1.]
 [ 1.  1.  1.]
 [ 1.  1.  1.]
 [ 1.  1.  1.]]

[[ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]]

首先,第6行似乎缺少一个逗号:

I = sp.array([0,1,4])
其次,我希望数组I中的值4会产生一个索引器,因为a和b的最大维度都是4。我想你可能想要:

I = sp.array([0,1,3])
让这些更改为我运行程序,我得到b作为:

[[ 0.  0.  1.  0.]
 [ 0.  0.  1.  0.]
 [ 0.  0.  1.  0.]]

我怀疑这就是您想要的。

似乎在将代码复制到问题时出现了一些错误

但我怀疑索引有一个已知的问题:

In [73]: a=np.zeros((2,3,4)); b=np.ones((3,4)); I=np.array([0,1])
制作
I
2个元素。索引
b
给出了预期的(3,2)形状。切片中有3行,索引中有2列

In [74]: b[:,I].shape
Out[74]: (3, 2)
但是用3d
a
我们得到了转置

In [75]: a[0,:,I].shape
Out[75]: (2, 3)
而赋值将产生一个错误

In [76]: b[:,I]=a[0,:,I]
...
ValueError: array is not broadcastable to correct shape
它将
I
定义的2个元素维度放在第一位,将
定义的3个元素放在第二位。这是一个混合高级索引的例子,前面已经讨论过了——还有一个bug问题。(我得查一下)

您可能正在使用较新的
numpy
(或
scipy
)并收到不同的错误消息

有文献表明,用两个数组或列表进行索引,并在中间切片,将切片放在末尾,例如

In [86]: a[[[0],[0],[1],[1]],:,[0,1]].shape
Out[86]: (4, 2, 3)
同样的事情也发生在
a[0,:,[0,1]]
上。但有一个很好的理由认为不应该这样

至于修复,您可以转置一个值,或者更改索引

In [88]: b[:,I]=a[0:1,:,I]

In [90]: b[:,I]=a[0,:,I].T

In [91]: b
Out[91]: 
array([[ 0.,  0.,  1.,  1.],
       [ 0.,  0.,  1.,  1.],
       [ 0.,  0.,  1.,  1.]])

In [92]: b[:,I]=a[0][:,I]


看起来您有一个输入错误:是否
[0,1 4]
实际上是
[0,1,4]
(逗号在1和4之间)?谢谢,我刚刚注意到这个测试用例确实运行,所以我更改了示例。由于某些原因,较小的数组大小并没有引起我遇到的错误。谢谢,这对了解。索引列表中间的切片被推到最后一个维度。