numpy抛出异常的逻辑索引

时间:2015-12-15 17:53:31

标签: python arrays matlab python-3.x numpy

我正在尝试编写一些使用逻辑numpy数组来索引更大数组的代码,类似于MATLAB允许使用逻辑数组进行数组索引的方法。

import numpy as np
m = 4
n = 4
unCov = np.random.randint(10, size = (m,n) )
rowCov = np.zeros( m, dtype = bool )
colCov = np.ones( n, dtype = bool )
>>> unCov[rowCov, rowCov] 
[]  # as expected
>>> unCov[colCov, colCov]
[0 8 3 3]  # diagonal values of unCov, as expected
>>> unCov[rowCov, colCov]
ValueError: shape mismatch: objects cannot be broadcast to a single shape

对于最后一次评估,我期望一个空数组,类似于MATLAB返回的数组。我不想在索引之前检查rowCov / colCov for True元素。为什么会发生这种情况,还有更好的方法吗?

1 个答案:

答案 0 :(得分:5)

根据我的理解,numpy会将您的2d逻辑索引转换为实际索引向量:arr[[True,False],[False,True]]对于arr[0,1]形状ndarray将变为(2,2)。但是,在最后一种情况下,第二个索引数组是完整的False,因此它对应于长度为0的索引数组。这与另一个完整的True索引向量配对,对应于索引数组长度4。

来自the numpy manual

  

如果索引数组的形状不同,则尝试进行   将它们播放到相同的形状。如果他们不能广播到   相同的形状,提出了一个例外:

在您的情况下,错误正是由此引起的:

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-1411-28e41e233472> in <module>()
----> 1 unCov[colCov,rowCov]

IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (4,) (0,)
另一方面,如果索引数组沿任何给定维度为空,则MATLAB会自动返回一个空数组。

这实际上突出了MATLAB中的逻辑索引与numpy之间的根本区别。在MATLAB中,下标索引中的向量总是切出一个子数组。就是这两个

arr([1,2],[1,2])

arr([true,true],[true,true])

将返回矩阵2 x 2的{​​{1}}子矩阵。如果逻辑索引向量短于数组的给定维度,则假定缺失的索引元素为arr。有趣的事实:只要多余的元素都是false,索引向量也可以更长而不是给定的维度。所以上面也等同于

false

arr([true,true,false,false],[true,true])

表示arr([true,true,false,false,false,false,false],[true,true]) 数组(为了参数)。

然而,在numpy中,以这种方式使用布尔值numpy 4 x 4进行索引将尝试提取向量。此外,布尔索引向量应与它们索引的维度长度相同。在您的arrays示例

4 x 4

unCov[np.array([True,True]),np.array([True,True])]

都返回两个第一对角元素,因此不是子矩阵而是向量。此外,他们还提出了那些不那么令人鼓舞的警告

unCov[np.array([True,True,False,False,False]),np.array([True,True,False,False,False])]

因此,在numpy中,您的逻辑索引向量应与/usr/bin/ipython:1: VisibleDeprecationWarning: boolean index did not match indexed array along dimension 0; dimension is 4 but corresponding boolean dimension is 5 的相应维度的长度相同。然后我上面写的内容是正确的:逻辑值被转换为索引,结果预期是一个向量。这个向量的长度是每个索引向量中ndarray元素的数量,所以如果你的布尔索引向量具有不同数量的True元素,那么引用没有意义,你得到你得到的错误。