在Python中切片危险的操作?

时间:2017-10-14 07:23:07

标签: python matlab python-3.x numpy

我正在阅读Python中的Ndarray documentation,它有以下示例。

  

大小为2 x 3的二维数组,由4字节整数组成   元素:

>>> x = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
>>> type(x)
<type 'numpy.ndarray'>
>>> x.shape
(2, 3)
>>> x.dtype
dtype('int32')
     

可以使用类似Python容器的语法对数组建立索引:

>>> # The element of x in the *second* row, *third* column, namely, 6.
>>> x[1, 2]
     

例如,切片可以生成数组的视图:

>>> y = x[:,1]
>>> y
array([2, 5])
>>> y[0] = 9 # this also changes the corresponding element in x
>>> y
array([9, 5])
>>> x
array([[1, 9, 3],
       [4, 5, 6]])

我有一个MATLAB背景,当我们y = x[:, 1]时,y成为一个独特的2x1矩阵,之后更改y的任何元素都不会对原始矩阵{{ 1}}。但是,似乎在Python中更改x的元素会改变原始数组y

有人可以评论是否应避免此操作吗?因为我不想通过操作数据的某些部分而意外地更改我的原始数据。

2 个答案:

答案 0 :(得分:1)

这绝对是Python的正确行为。该语言的最大好处之一是所有内容都作为参考而不是值传递。如果您真的想要从切片创建新矩阵,请考虑.copy方法。

答案 1 :(得分:1)

numpy数组中的切片是对象的视图(与列表中将返回新对象的切片不同),这意味着您获得的值是对原始数组的引用。引用文章Views versus copies in NumPy,强调我的:

  

NumPy数组的视图是什么?

     

顾名思义,它只是查看数组数据的另一种方式。从技术上讲,这意味着两个对象的数据是共享的。您可以通过选择原始数组的切片或通过更改dtype(或两者的组合)来创建视图。这些不同类型的观点如下所述。

     

切片视图

     

这可能是最常见的视图创作来源!NumPy。   创建切片视图的经验法则是查看过的视图   元素可以通过偏移,步幅和计数来解决   原始数组。例如:

>>> a = numpy.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> v1 = a[1:2]
>>> v1
array([1])
>>> a[1] = 2
>>> v1
array([2])

当您使用切片时,因为您想要查看部分数据或对其执行就地执行操作,这是完全安全的。如果您希望就地修改数据,那么您希望使用np.copy()

创建元素的新副本
>>> a = np.array([1, 5, 3, 7, 2, 3, 1, 8, 5])
>>> b = a[1:5]
>>> b
array([5, 3, 7, 2])
>>> # this will create a new array and sort it
>>> np.sort(b)
array([2, 3, 5, 7])
>>> b
array([5, 3, 7, 2])
>>> # this is done in-place, which means it will also affect `a`
>>> b.sort()
>>> a
array([1, 2, 3, 5, 7, 3, 1, 8, 5])