Numpy 高级索引和基本索引
Posted
技术标签:
【中文标题】Numpy 高级索引和基本索引【英文标题】:Numpy Advanced Indexing and basic indexing 【发布时间】:2018-08-31 06:50:27 【问题描述】:我正在尝试了解this article 的特定部分。
高级索引的定义意味着
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 a 而bb = a[(2,2),]
将保持不变。
这一切有什么问题?我是否误解或遗漏了重要的东西?
如果是,请指正并提前感谢!
【问题讨论】:
【参考方案1】:“基本选择”(即索引而不是切片)不会创建视图,而是创建副本。为了成为一个视图,您需要传递一个单元素切片(切片与索引不同,始终是一个视图)。
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)
这样的 0-dim 数组可以像普通的 int
一样使用。
为了更令人困惑,a[2,2]
在等号左侧被解释为视图,而不是在右侧。它与=
被解释为.__setitem__()
有关。
【讨论】:
我想我理解你的大部分答案,但你能解释一下 b = a[2, 2, None].squeeze() ,索引末尾的 None 代表什么?我前几天才看到这个,但仍然无法弄清楚这是什么!谢谢! 我使用类似 b=a[2,2,...] 的操作,似乎返回视图!这两个操作(:和...)是否真的触发了基本索引? 是的,a[2,2,...]
触发花式索引,因为...
本质上意味着“包括所有其他维度”,即使没有其他维度,它也算作一个切片。由于您随后混合了切片和索引,因此它被认为是“花哨的”并且它返回一个视图。可能是最好的解决方案,因为它不需要squeeze()
:
只会在实际存在维度时触发精美的索引。如果你这样做a[2,2,:]
,你会得到一个IndexError
,因为a
没有第三维度
None
添加了另一个维度(它与np.newaxis
相同,但写起来更短),它被认为是一个切片。然后,您可以使用 squeeze()
摆脱该维度以上是关于Numpy 高级索引和基本索引的主要内容,如果未能解决你的问题,请参考以下文章