布尔索引但实为其他操作
我在尝试做布尔索引,但遇到了一些问题。
np.random.randn(8).reshape((4,2))
Out[11]:
array([[-1.13058416, 1.08397186],
[-1.2730122 , 0.78306498],
[-0.05370502, -1.16723298],
[ 1.01750955, -0.95029671]])
a=np.random.randn(8).reshape((4,2))
a[[2==3,3==0,0==0,1!=1]]
Out[13]:
array([[ 0.18235299, -2.53482367],
[ 0.18235299, -2.53482367],
[-1.03752809, -2.2790847 ],
[ 0.18235299, -2.53482367]])
这到底发生了什么?我原本想的是布尔索引。这个操作是什么?我并不是在问怎么把这个改成布尔索引,而是想知道这个操作到底在干嘛?这样做可以吗?
1 个回答
可以把 ndarray
想象成升级版的 list
。在数组上进行的广播和操作会自动扩展到参与这些操作的列表上,所以你可以把一个数组和一个形状兼容的列表相加,而 numpy 不会试图把它们合并在一起(就像它会对两个列表那样做)。
有一个很大的(对我来说也很困惑的)例外情况就是花式索引。花式索引本身就让我感到困惑(因为我之前用的是 MATLAB),因为下面这两个操作的结果却不一样,这让我觉得很奇怪:
import numpy as np
A = np.random.rand(3,3)
A[0:1,0:1]
A[range(2),range(2)]
前者是一个切片操作,返回一个 2x2 的子矩阵。而后者是花式索引的例子,只返回一个包含 A[0,0]
和 A[1,1]
的 2 元素数组。
你的问题和另一个同样奇怪的情况有关:在花式索引中,布尔值的列表和数组表现得不一样。考虑下面这两个例子,和你的问题类似:
A = np.random.rand(4,2)
bool_index_list = [False, True, True, False]
bool_index_array = np.array(bool_index_list)
A[bool_index_list].shape
A[bool_index_array].shape
前者返回 (4,2)
,而后者返回 (2,2)
。
在前面的例子中,由于索引是一个 list
,布尔值会被转换成对应的整数,结果 [0,1,1,0]
被用作矩阵中的实际索引,分别返回 [第一行, 第二行, 第二行, 第一行]。
在后面的例子中,dtype=bool
的索引 array
按照你预期的方式使用:它作为一个掩码,忽略那些索引为 False
的 A
的行。
numpy 的发布说明中提到,
将来,布尔数组(比如 Python 布尔值的列表)将始终被视为布尔索引,而布尔标量(包括 Python 的
True
)将是合法的 布尔 索引。
因此,上面基于列表的索引在 numpy 1.10.1 中给我带来了以下警告:
FutureWarning: 在未来,布尔数组将被视为布尔数组索引
所以简单来说,你的问题是合法的,但这种情况不会持续太久。最好还是使用 ndarray
的花式索引,这样你就不会遇到麻烦了。