首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Numpy数组索引:查看还是复制-取决于范围?

Numpy数组索引:查看还是复制-取决于范围?
EN

Stack Overflow用户
提问于 2021-12-21 21:01:29
回答 2查看 152关注 0票数 1

考虑以下数组操作:

代码语言:javascript
复制
import numpy as np
def f(x):
     x += 1
x = np.zeros(1)
f(x)       # changes `x`
f(x[0])    # doesn't change `x`
x[0] += 1  # changes `x`

为什么x[0]的行为不同,取决于+= 1是发生在函数f内部还是外部

我能否将数组的一部分传递给函数,以便函数修改原始数组?

编辑:如果我们考虑的是=而不是+=,我们可能会保持问题的核心,同时消除一些不相关的复杂性。

EN

回答 2

Stack Overflow用户

发布于 2021-12-21 23:18:36

您甚至不需要函数调用就可以看到这种差异。

x是一个数组:

代码语言:javascript
复制
In [138]: type(x)
Out[138]: numpy.ndarray

索引数组中的元素将返回一个np.float64对象。它实际上将数组中的值“取出来”;它不是对数组元素的引用。

代码语言:javascript
复制
In [140]: y=x[0]
In [141]: type(y)
Out[141]: numpy.float64

这个y很像蟒蛇浮子;您可以用同样的方式进行+=

代码语言:javascript
复制
In [142]: y += 1
In [143]: y
Out[143]: 1.0

但是这不会改变x

代码语言:javascript
复制
In [144]: x
Out[144]: array([0.])

但这确实改变了x

代码语言:javascript
复制
In [145]: x[0] += 1
In [146]: x
Out[146]: array([1.])

y=x[0]进行x.__getitem__调用。x[0]=3进行x.__setitem__调用。+=使用__iadd__,但实际上类似。

另一个例子是:

改变x

代码语言:javascript
复制
In [149]: x[0] = 3
In [150]: x
Out[150]: array([3.])

但是,对y做同样的尝试失败了:

代码语言:javascript
复制
In [151]: y[()] = 3
Traceback (most recent call last):
  File "<ipython-input-151-153d89268cbc>", line 1, in <module>
    y[()] = 3
TypeError: 'numpy.float64' object does not support item assignment

y[()]是允许的。

对带有片的数组进行basic索引确实会产生一个可以修改的view

代码语言:javascript
复制
In [154]: x = np.zeros(5)
In [155]: x
Out[155]: array([0., 0., 0., 0., 0.])
In [156]: y= x[0:2]
In [157]: type(y)
Out[157]: numpy.ndarray
In [158]: y += 1
In [159]: y
Out[159]: array([1., 1.])
In [160]: x
Out[160]: array([1., 1., 0., 0., 0.])

===

Python和切取x[0]+=1类型操作的示例:

代码语言:javascript
复制
In [405]: alist = [1,2,3]
In [406]: alist[1]+=12
In [407]: alist
Out[407]: [1, 14, 3]
In [408]: adict = {'a':32}
In [409]: adict['a'] += 12
In [410]: adict
Out[410]: {'a': 44}

__iadd__可以被认为是一个__getitem__,后面是一个具有相同索引的__setitem__

票数 2
EN

Stack Overflow用户

发布于 2021-12-26 00:13:00

根据这句话这个答案

  • x[0]f(x[0])中在x上执行__getitem__。在这种特殊情况下(例如,与索引数组的一个片段相反),此操作返回的值不允许修改原始数组。
  • x[0] = 1x上执行__setitem__

可以定义/重载__getitem____setitem__来执行任何操作。他们甚至不一定要保持一致。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70441552

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档