让我们引用纽比手册:https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#advanced-indexing
Advanced indexing is triggered when the selection object, obj, is a non-tuple sequence object, an ndarray (of data type integer or bool), or a tuple with at least one sequence object or ndarray (of data type integer or bool). There are two types of advanced indexing: integer and Boolean.
Advanced indexing always returns a copy of the data (contrast with basic slicing that returns a view).
然后,对高级索引返回的内容进行操作时,绝不应修改原始数组。事实上:
import numpy as np
arr = np.array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
indexes = np.array([3, 6, 4])
slicedArr = arr[indexes]
slicedArr *= 5
arr
打印:
^{pr2}$然而,情况并非总是如此。奇怪的是,如果我不将[]
运算符返回的内容保存到中间变量,那么我将以某种方式对原始数组进行操作。请考虑这个例子:
import numpy as np
arr = np.array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
indexes = np.array([3, 6, 4])
arr[indexes] *= 5
arr
打印:
array([ 0, 10, 20, 150, 200, 50, 300, 70, 80, 90])
我不抱怨。实际上,这是我的救命稻草。然而,我不明白为什么这是有效的,我真的很想了解这一点。在
据我所知,只要我写arr[indexes]
我就在创建数组的一个副本;因此后续的*= 5
应该在这个副本上操作,而不是在原始数组上操作。但是,应该丢弃此计算的结果,因为它不会写入任何变量。在
但显然我错了。在
我的误会在哪里?在
While语句
以及
^{pr2}$看起来很相似,其实根本不同。第一个将名称“a”绑定到expr。 第二个或多或少是equivalent到{}。}。
特别是,不创建中间对象“表示
__setitem__
实际做什么取决于实现它的人,但是传统的语义是用x
所指示的位置用expr
更新容器对象{a[x]
”。在为了完整起见,
a[x]
如果它不在语法上看起来像是赋值的l.h.s.,那么它或多或少等同于a.__getitem__(x)
。在更新以回答后续问题(执行
^{3}$a[x] *= 5
时会发生什么情况?)让我们用仪器来测试相关的方法,这样我们就能知道发生了什么。下面,__imul__
是就地乘法的“神奇方法”:印刷品:
关键是
在第二个示例中,没有使用索引返回任何内容。您只使用索引来修改值。所以你要修改的对象就是原始对象。不是拷贝。在
相关问题 更多 >
编程相关推荐