【问题标题】:numpy slice assign to another valuenumpy 切片分配给另一个值
【发布时间】:2019-05-29 14:42:26
【问题描述】:

假设我有一个 1D numpy 数组:

 arr = np.arange(10)

然后我将 arr 切片并赋值给另一个变量:

 arr2 = arr[5:8]

我想改变 arr :

 arr2 *= 10

或:

 arr2 = arr2 * 10

结果不同。为什么它们不同?

 arr

数组([ 0, 1, 2, 3, 4, 50, 60, 70, 8, 9])

 arr

数组([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

【问题讨论】:

标签: python numpy


【解决方案1】:

简而言之,arr2 = arr[5:8] 将对arr5:7th 元素的引用分配给变量arr2

因此,arr2 *= 10 操作归结为“将这些元素乘以 10”,这会在原地修改 arr(您正在对引用执行就地操作、修改,因此会影响原创)。

但是,arr2 = arr2 * 10 表示“将第 5:7 元素乘以 10 的结果,然后将其分配给名为 arr2 的变量”。在这里,您对引用执行操作(不是修改),获取输出(明确地说,操作arr2 * 10 返回一个新对象),并将其分配给arr2,它顺便破坏了原始参考(但这部分有点无关紧要)。

或者比较一下:

arr[5:8] *= 10
arr[5:8] = arr[5:8] * 10
arr2 = arr[5:8] * 10

前两个是等价的。您的代码本质上是第一个和第三个(相当于第二个和第三个)之间的比较。第二个和第三个不相等,因为在您的代码中,您之前对arr2 = arr[5:8] 的赋值与arr2 = arr[5:8] * 10 的LHS 无关。

【讨论】:

    【解决方案2】:
    In [639]: arr = np.arange(10)         
    

    通过使用切片进行索引(基本索引),arr2viewarr。它与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 的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-19
      • 2020-04-01
      • 2016-04-18
      • 2017-03-06
      • 2018-07-30
      • 2018-07-14
      • 2015-05-28
      • 2017-01-29
      相关资源
      最近更新 更多