NumPy高级索引和基本索引

3

我正在尝试理解这篇文章的一个具体部分。

高级索引的定义意味着 x[(1,2,3),]x[(1,2,3)] 有根本的区别。后者等同于 x[1,2,3],将触发基本选择,而前者将触发高级索引。请确保理解其原因。

我已经尝试了以下代码。

>>> import numpy as np 
>>> a = np.arange(50).reshape(5,10)    
>>> b = a[(2,2)]    
>>> bb = a[(2,2),]    
>>> a[2,2] = 50 # a[2,2] was 22 in the first place 
>>> b
22  # this outcome confuses me!

我认为b = a[(2,2)]会得到一个视图,所以当我改变a[2,2]时,它也会改变。

bb = a[(2,2),]会接收副本,因此即使我对a进行操作,也不会发生任何事情。

但是当我将a[2,2]从22改为50时

我期望b = a[(2,2)]会改变为50,而bb = a[(2,2),]仍然保持不变。

这其中有什么问题吗?我是否理解有误或者漏掉了一些重要的东西?

如果是这样,请指正我,非常感谢!

1个回答

0
"

基本选择(即索引而非切片)不会创建视图,它会创建一个副本。要成为视图,您需要传递一个单元素切片(与索引不同,切片始终是视图)。

"
import numpy as np 
a = np.arange(50).reshape(5,10)    
b = a[2:3,2:3].squeeze()    
a[2,2] = 50 
b

array(50)

你也可以使用 b = a[2, 2, None].squeeze() 来获得相同的结果,这会触发“高级”索引,它是选择和切片之间的一种混合形式,并返回一个视图。使用“高级”索引(就像你所做的或者 b = a[[2],[2]])是索引的一种变体,它返回一个副本。

是的,对于初学者来说,区分这些不同类型的索引并不容易。而且创建一个元素的视图仍然有点hacky。像 array(50) 这样的零维数组在大多数情况下可以像普通的 int 一样使用。

为了让事情更加混乱,a[2,2] 在等号左边时被解释为视图,但在右边时却不是。这与 = 被解释为 .__setitem__() 有关。


我认为我理解了你回答的大部分内容,但是你能否解释一下 b = a[2, 2, None].squeeze(),索引结尾处的 None 是什么意思?我前几天看到过这个,但仍然无法弄清楚它是什么!谢谢! - H_E_A_D
我使用类似 b=a[2,2,...] 的操作,它似乎返回视图!这两个操作(:和...)是否实际触发了基本索引? - H_E_A_D
是的,a[2,2,...] 触发了花式索引,因为 ... 实际上意味着“包括所有其他维度”,即使没有其他维度,它也算作一个切片。由于您正在混合切片和索引,因此被认为是“花式”并返回一个视图。这可能是最好的解决方案,因为它不需要 squeeze() - Daniel F
: will only trigger fancy indexing if there is actually a dimension there. If you do a[2,2,:] you'll get an IndexError becasue there is no third dimension in a - Daniel F
None adds another dimension (it's the same as np.newaxis but shorter to write) which is considered a slice. You then get rid of that dimension with squeeze() - Daniel F
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接