我对最后一个表达式的结果感到惊讶吗?
>>> from numpy import array, arange
>>> a = arange(12).reshape(3,4)
>>> b1 = array([False,True,True]) # first dim selection
>>> b2 = array([True,False,True,False]) # second dim selection
>>>
>>> a[b1,:] # selecting rows
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>>
>>> a[b1] # same thing
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>>
>>> a[:,b2] # selecting columns
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
>>>
>>> a[b1,b2] # a weird thing to do
array([ 4, 10])
我期望:
array([[ 4, 6],
[ 8, 10]])
您对此有何解释?
答案 0 :(得分:4)
让我们从您的数组开始:
a = np.array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
您当前的索引逻辑等同于以下内容:
a[[1, 2], [0, 2]] # array([ 4, 10])
NumPy选择2维,将其解释为索引dim1索引[1, 2]
和dim2索引[0, 2]
,或坐标(1, 0)
和(2, 2)
。这里没有广播。
要允许使用布尔数组进行广播,可以使用numpy.ix_
:
res = a[np.ix_(b1, b2)]
print(res)
array([[ 4, 6],
[ 8, 10]])
docs中指出了ix_
所具有的魔力:“布尔序列将被解释为对应维的布尔掩码(等效于传递np.nonzero(boolean_sequence)
)。”
print(np.ix_(b1, b2))
(array([[1],
[2]], dtype=int64), array([[0, 2]], dtype=int64))
请注意,如果您有整数索引,可以使用更直接的方法:
b1 = np.array([1, 2])
b2 = np.array([0, 2])
a[b1[:, None], b2]
另请参见:related question关于此方法不适用于布尔数组的原因。