在对数组进行某些操作的时候,会生成一个新的数组作为结果返回,新数组存放的数据有时是原数组元素的一个拷贝,修改其中的数据不会影响到原数组,他们是相互独立的;有时却又和原数组是数据共享的,修改其中一个数组的数据,另外一个也变了。
前者生成的是数组的拷贝,后者生成的是数组的一个视图。
视图
在前面遇到的很多操作,比如转置,修改尺寸,切片等操作都只是返回了原数组的一个视图作为结果。虽然用id()函数查看它们,返回的是不同的编号,这仅仅意味着它们是不同的对象,但不能保证其中存储的数据是独立的。
import numpy as np"""1. 转置"""a = np.array([[1, 2], [3, 4]])b = a.T # 返回的是 a 的一个视图print(id(a), id(b)) # 2668490408304 2668490408384a[0, 0] = 666 # 修改 a,b 也修改了print(b)# [[666 3]# [ 2 4]]"""2. 修改尺寸"""a = np.arange(4)b = a.reshape(2, 2)a[0] = 666print(b)# [[666 3]# [ 2 4]]"""3. 切片"""a = np.arange(4)b = a[:2] # array([0, 1])b[0] = 666print(a) # [666 1 2 3]
几种区分方式
import numpy as np"""ndarray.base如果对象的内存来自其他对象,则返回那个对象,否则返回 None"""a = np.arange(4)b = a[::]print(a.base is None) # Trueprint(b.base is a) # True"""ndarray.flags.owndataflags 属性里存储了很多数组内存布局的的一些信息flags.owndata 很直观,表示是否拥有真正的数据"""print(a.flags.owndata) # Trueprint(b.flags.owndata) # False 数据相当于是从 a 那边「借」过来的
拷贝
如果有时确实想得到有完全独立数据的新数组,这时就可以使用ndarray.copy()方法,在前面「数组的索引」小节介绍过。
import numpy as npa = np.arange(6).reshape(2, 3)b = a.T.copy()print(b.base) # Noneprint(a.flags.owndata) # True
