我没想到它们会有所不同,直到我花了 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/