问题描述
根据numpy - why Z[(0,2)] is view but Z[(0,2),(0)] is copy?的回答,现在明白逗号可以触发advanced indexing,文档中也有警告。
警告高级索引的定义意味着 x[(1,2,3),] 是 根本不同于 x[(1,3)]。后者相当于 x[1,3] 这将触发基本选择,而前者将 触发高级索引。请务必了解发生这种情况的原因。
一旦提前索引用逗号触发,元组索引是否与数组索引相同?如果是这样,为什么有两种方法可以做同样的事情?
如果不是,请帮助理解为什么以及背后的理性/决定来破译这些麻木行为。
Z = np.arange(12).reshape(3,4)
print("Z is \n{}\n".format(Z))
print("Z[[1,2],[1]] is \n{} Is view {}\n__array_interface__ {}\n".format(
Z[
[1,[1]
],Z[[1,[1]].base is not None,[1]].__array_interface__
))
# Comparison with tuple indexing
print("Z[(1,(1)] is \n{} Is view {}\n__array_interface__ {}\n".format(
Z[
(1,(1)
],Z[(1,(1)].base is not None,(1)].__array_interface__
))
---
Z is
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
Z[[1,[1]] is
[5 9] Is view False
__array_interface__ {'data': (94194177532720,False),'strides': None,'descr': [('','<i8')],'typestr': '<i8','shape': (2,),'version': 3}
Z[(1,(1)] is
[5 9] Is view False
__array_interface__ {'data': (94194177118656,'version': 3}
解决方法
Z[[1,2],[1]]
用列表 [1,2] 索引第一个维度,用列表 [1] 索引第二个维度。实际上索引 np.array([1,2])
是针对 np.array([1])
广播的。所以它是来自第 1 行和第 2 行以及第 1 列的 2 个元素。
Z[(1,2),(1)]
是一样的。两者都有一个逗号,用于创建一个传递给 __getitem__
方法的外部元组。 np.array((1,2))
与 np.array([1,2])
相同。 (1)
不是元组,它只是 1
(没有逗号)。同样,第 1 行和第 2 行,第 1 列。
Z[(x,y)]
与 Z[x,y]
相同;构成元组的是逗号,而不是 ()。
x[(1,2,3),]
逗号创建了一个元组 ((1,)
,实际上告诉 x.__getitem__
我们正在从 x
的第一个维度中进行选择。 x[[1,3],]
和 x[np.array([1,3]),]
相同。
x[(1,3)]
等价于 x[1,3]
,为 x
的 3 个维度提供标量索引。