视图和复制

阅读: 5332     评论:1

在操作或变换数组的时候,有时候会修改数组本身,有时候又不会,这往往让新手很迷惑。具体有下面三种情况:

1. 完全不复制

下面的结果,是因为数组是一个可变的对象:

>>> a = np.arange(12)
>>> b = a            # 不会创建新的数组对象,而是多了一个引用
>>> b is a           # a和b只是同一个数组的两个名字
True
>>> b.shape = 3,4    # 会同时修改a的形状
>>> a.shape
(3, 4)

参考Python的例子:

>>> a = [1,2,3]
>>> b=a
>>> b is a
True
>>> b.reverse()
>>> b
[3, 2, 1]
>>> a
[3, 2, 1]

2. view视图

不同的数组对象可以共享同样的数据。view方法就可以实现这一操作:

>>> c = a.view()   # 现在开始c是一个新的数组,并且和a共享数据
>>> c is a      # 说明c和a是两个不同的对象
False
>>> c.base is a                        # c是a数组的数据视图
True
>>> c.flags.owndata     # 可以看到c没有自己的数据
False
>>>
>>> c.shape = 2,6                      # a的形状不会发生改变
>>> a.shape
(3, 4)
>>> c[0,4] = 1234                      # 但是a的数据会跟着发生改变
>>> a
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])

理解view,只需要注意两者共享数据,此外其它所有都是独立的。

切片操作,则会返回一个数组的view视图:

>>> s = a[ : , 1:3]     
>>> s[:] = 10           # s[:]是s的一个视图。注意与s=10区分开,不要混淆。
>>> a
array([[   0,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])

3. 深度拷贝

copy方法生成数组的一个完整的拷贝,包括其数据。

>>> d = a.copy()                         
>>> d is a
False
>>> d.base is a                     
False
>>> d[0,0] = 9999
>>> a
array([[   0,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])

 分割数组 广播机制 

评论总数: 1


点击登录后方可评论

总结:视图共享数据