Python 为什么索引数组的行为与numpy用户文档中记录的一样?

Python 为什么索引数组的行为与numpy用户文档中记录的一样?,python,numpy,scipy,Python,Numpy,Scipy,示例 关于的文档为那些天真的程序员展示了一个具有意外结果的示例 >>> x = np.arange(0, 50, 10) >>> x array([ 0, 10, 20, 30, 40]) >>> x[np.array([1, 1, 3, 1])] += 1 >>> x array([ 0, 11, 20, 31, 40]) 文档中说,人们可能天真地期望数组在x[1]+1处的值增加三倍,但实际上它被分配给x[1]三倍 问题

示例

关于的文档为那些天真的程序员展示了一个具有意外结果的示例

>>> x = np.arange(0, 50, 10)
>>> x
array([ 0, 10, 20, 30, 40])
>>> x[np.array([1, 1, 3, 1])] += 1
>>> x
array([ 0, 11, 20, 31, 40])
文档中说,人们可能天真地期望数组在
x[1]+1
处的值增加三倍,但实际上它被分配给
x[1]
三倍

问题

真正让我困惑的是,我所期望的是操作
x+=1
的行为与普通Python中的操作一样,就像
x=x+1
,因此
x
产生
数组([11,11,31,11])
。如本例所示:

>>> x = np.arange(0, 50, 10)
>>> x
array([ 0, 10, 20, 30, 40])
>>> x = x[np.array([1, 1, 3, 1])] + 1
>>> x
array([11, 11, 31, 11])
问题

第一:

原始示例中发生了什么?有人能详细解释一下吗

第二:


这是一种记录在案的行为,我同意。但我认为它应该像我描述的那样,因为这是从蟒蛇学的角度所期望的。所以,仅仅因为我想被说服:有没有一个很好的理由让它表现得像是超越了“我预期的”行为?

问题是,你给出的第二个例子与第一个不同。如果您分别查看
x[np.array([1,1,3,1])]+1的值,就会更容易理解,numpy在两个示例中都会计算该值

x[np.array([1,1,3,1])]+1的值是您所期望的:
array([11,11,31,11])

在示例1中,将此答案指定给原始数组x中的元素1和3。这意味着新值11被分配给元素1三次

但是,在示例2中,您使用新的数组
数组([11,11,31,11])
替换原始数组x

这是第一个示例的正确等效代码,并给出了相同的结果

>>> x = np.arange(0, 50, 10)
>>> x
array([ 0, 10, 20, 30, 40])
>>> x[np.array([1, 1, 3, 1])] = x[np.array([1, 1, 3, 1])] + 1
>>> x
array([ 0, 11, 20, 31, 40])

不知道NumPy的内部结构,但可能是因为+=是一个就地操作,+不是。我怀疑在第一种情况下,创建了数组的视图(忽略double),然后应用了+=操作。在第二种情况下,我怀疑有人首先复制了视图,然后进行了+操作。(对我来说似乎并不不合理(NumPy有时不像Python,更像C/Fortran(有充分的理由)))谢谢!最后一个代码清单非常有用。我告诉我,我首先误解了“+=”运算符。(x[y]+=1--[相当于]->x[y]=x[y]+1),(x[y]+=1--[不相当于]-->x=x[y]+1)
>>> x = np.arange(0, 50, 10)
>>> x
array([ 0, 10, 20, 30, 40])
>>> x[np.array([1, 1, 3, 1])] = x[np.array([1, 1, 3, 1])] + 1
>>> x
array([ 0, 11, 20, 31, 40])