python - 使用整数和 numpy 标量索引 numpy 数组时有什么区别?

标签 python arrays numpy indexing

我没想到它们会有所不同,直到我花了 2 个小时才找到一个错误。这是一个示例,显示了我注意到的差异,但我无法理解它。

>>> a = np.array([[1, 2], [3, 4]])
>>> a[0][0]
1
>>> a[np.array(0)][np.array(0)]
1
>>> a[0][0] = 5
>>> a
array([[5, 2],
       [3, 4]])
>>> a[np.array(0)][np.array(0)] = 6
>>> a
array([[5, 2],
       [3, 4]])

看起来使用 numpy 标量作为索引元素无法更改。是否返回原始数组元素的副本而不是引用?

但是,使用元组索引,问题就消失了。

>>> a[np.array(0), np.array(0)] = 6
>>> a
array([[6, 2],
       [3, 4]])

这里发生了什么?我理解链括号索引和元组索引在语义上是不同的,但原则上它们不应该都访问相同的元素吗?

出于好奇,我尝试了一维数组。结果不同。

>>> a = np.array([1, 2])
>>> a[np.array(0)] = 3
>>> a
array([3, 2])

这次元素已被修改。

我学到的教训是,为了安全起见,我应该尽可能多地对 numpy 数组使用元组索引。但我真的很想对这些不一致的效果做出解释。谢谢!

最佳答案

查看数据缓冲区位置:

In [45]: a.__array_interface__['data']
Out[45]: (44666160, False)
In [46]: a[0].__array_interface__['data']
Out[46]: (44666160, False)

a[0] 案例的位置相同。修改 a[0] 将修改 a

但是对于数组索引,数据缓冲区是不同的 - 这是一个副本。修改此副本不会影响a

In [47]: a[np.array(0)].__array_interface__['data']
Out[47]: (43467872, False)

a[i,j] 索引比 a[i][j] 更惯用。在某些情况下它们是相同的。但有足够多的情况表明它们有所不同,明智的做法是避免后者,除非您真的知道它的作用和原因。

In [49]: a[0]
Out[49]: array([1, 2])
In [50]: a[np.array(0)]   
Out[50]: array([1, 2])
In [51]: a[np.array([0])]
Out[51]: array([[1, 2]])

使用 0 维数组 np.array(0) 进行索引就像使用 1 维数组 np.array([0]) 进行索引。两者都会生成一个副本,其第一个维度的大小与索引相同。

诚然,这很棘手,除非进行此类设置,否则可能不会出现。

<小时/>

使用np.matrix时,[i][j][i,j]的选择也会影响形状 - python difference between the two form of matrix x[i,j] and x[i][j]

关于python - 使用整数和 numpy 标量索引 numpy 数组时有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52323524/

相关文章:

python - Pandas DataFrame 未按预期工作

python - 如何在 django 中使 @cached_property 无效

java - 使用数组项设置按钮文本

c++ - 在 if(指针)条件内递增指针

java - Java中用于保存存储桶列表ID的默认结构

python - Numpy 数组改变内部元素的值

python - 将嵌套列表转换为 numpy 数组的有效方法

python - 比较python中嵌套列表中列表的第一个元素

python - 如何连续多次从列表中生成随机项目,但每次都会生成不同的项目

python - 使用 Python Pillow lib 设置颜色深度