假设我有一个一维的numpy数组:
arr = np.arange(10)
然后我将arr切片并分配给另一个变量:
arr2 = arr[5:8]
我想更改arr:
arr2 *= 10
或:
arr2 = arr2 * 10
结果不同。他们为什么不同?
arr
array([0,1,2,3,4,50,60,70,8,9])
arr
array([0,1,2,3,4,5,6,7,8,9])
答案 0 :(得分:1)
简而言之,arr2 = arr[5:8]
将对5:7
的第arr
个元素的引用分配给变量arr2
。
因此,arr2 *= 10
操作归结为“将这些元素乘以10个就位”,从而修改了arr
就地(您正在执行就地操作,对参考进行修改,因此会影响原始图片。
但是,arr2 = arr2 * 10
表示“将第5:7个元素乘以10,然后将其分配给名为arr2
的变量”。在这里,您对引用执行操作(不是修改),获取输出(明确地说,操作arr2 * 10
返回一个新对象),并将其分配给{{1 }},这会偶然破坏原始参考(但这部分是不相关的)。
或比较这些:
arr2
前两个是等效的。您的代码本质上是第一个和第三个(等效地,第二个和第三个)之间的比较。第二个和第三个不相等,因为在您的代码中,您先前分配的arr[5:8] *= 10
arr[5:8] = arr[5:8] * 10
arr2 = arr[5:8] * 10
与arr2 = arr[5:8]
的LHS无关。
答案 1 :(得分:0)
In [639]: arr = np.arange(10)
通过使用切片建立索引(基本索引),arr2
是view
中的arr
。它与arr
共享数据缓冲区:
In [640]: arr2 = arr[5:8]
In [641]: arr2
Out[641]: array([5, 6, 7])
如果我们进行复制,则值将被复制而不是共享:
In [642]: arr3 = arr[5:8].copy() # arr[[5,6,7]] is also a copy
通过就地修改arr2
,我们还修改了arr
的一部分:
In [643]: arr2 *= 10
In [644]: arr2
Out[644]: array([50, 60, 70])
In [645]: arr
Out[645]: array([ 0, 1, 2, 3, 4, 50, 60, 70, 8, 9])
但不是arr3
:
In [646]: arr3
Out[646]: array([5, 6, 7])
arr2 = arr2*10
不会修改arr2
数组,而是为arr2
变量分配一个全新的数组。
因此,您需要了解将对象分配给变量的含义。分配变量和修改可变对象之间的区别。以及数组复制和视图(以及基本索引和高级索引)之间的区别。最后一个特定于numpy
,其余的特定于Python。