在操作或变换数组的时候,有时候会修改数组本身,有时候又不会,这往往让新手很迷惑。具体有下面三种情况:
下面的结果,是因为数组是一个可变的对象:
>>> 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]
不同的数组对象可以共享同样的数据。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]])
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]])
总结:视图共享数据