《玩转Numpy计算库》视频课程
《玩转Numpy计算库》视频课程链接:https://edu.csdn.net/course/detail/28656
7. 拷贝和视图 (Copies and Views)
在操作数组时,有时会将其数据复制到新数组中,而有时不复制。 对于初学者来说,这通常会引起混淆。 有以下三种情况:
1) 不复制 (No Copy at All)
简单的赋值不会复制数组对象或其数据。
a = np.arange(12)
b = a # no new object is created
b is a # a and b are two names for the same ndarray object
b.shape = 3,4 # changes the shape of a
a.shape
Python将可变对象作为引用传递,因此函数调用不会复制。
def f(x):
print(id(x))
id(a) # id is a unique identifier of an object
f(a)
2) 视图或浅拷贝 (View or Shallow Copy)
不同的数组对象可以共享相同的数据。 view方法创建一个新的数组对象,该对象和原来的数组对象看到相同的数据。如果在view上修改数据,会直接反馈到原始对象。
c = a.view()
c is a
c.base is a # c is a view of the data owned by a
c.flags.owndata
c.shape = 2,6 # a's shape doesn't change
a.shape
c[0,4] = 1234 # a's data changes
c
a
对一个数组切片将返回它的一个view:
s = a[ : , 1:3] # spaces added for clarity; could also be written "s = a[:,1:3]"
s[:] = 10 # s[:] is a view of s. Note the difference between s=10 and s[:]=10
a
3) 深拷贝 (Deep Copy)
这种复制方法对数组及其数据进行一个完整复制。对新生成的对象修改删除操作不会影响到原对象。
d = a.copy() # a new array object with new data is created
d is a
d.base is a # d doesn't share anything with a
d[0,0] = 9999
d
a
如果不再需要原始数组,有时在切片后应调用copy。
例如,假设a是一个巨大的中间结果的数组,而最终结果b仅包含a的一小部分,则在使用切片构造b时应进行深拷贝:
a = np.arange(int(1e8))
b = a[:10].copy()
del a # the memory of ``a`` can be released.
b
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
如果改用b = a [:10]
,则a被b引用,并且即使执行del a
, b也将保留在内存中。
a = np.arange(int(1e8))
b = a[:10]
del a
b
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])