ndarray对象的赋值、浅拷贝与深拷贝 | 机器学习 |《python学习之路》| python 技术论坛-江南app体育官方入口
赋值、浅拷贝与深拷贝
当我们操作ndarray对象时,他们的数据存在着三种常见的操作:赋值、浅拷贝与深拷贝,分清楚操作的核心才能清楚ndarray对象是否改变
- 赋值
- 当ndarray对象被赋值操作时,跟python里的赋值操作一样,都是将新对象的指针指向赋值对象的内存,所以当我们改变被赋值对象时,赋值对象也会跟着改变
- demo
>>> import numpy as np >>> a = np.arange(12).reshape(4,3) >>> a array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]]) >>> b = a >>> b is a true >>> b.shape = 3,4 >>> a.shape (3, 4) >>> a array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
- 浅复制or视图(在numpy中文文档里是浅复制,实际测试中base为false但是又可以改变原ndarray,测试版本为numpy 1.16.2)
- 在numpy中可以使用view方法创建一个新的数组对象,它与原数组对象共享数据,具体来说,b = a[:]会创建一个新的对象 b,所以 id(b) 和id(a) 返回的结果是不一样的,但是 b 的数据完全来自于a,和 a 保持完全一致,换句话说,b的数据完全由a保管,他们两个的数据变化是一致的。切片本质上也是视图操作,所有的切片操作返回的都是视图。
- demo
>>> c = a.view() # 使用view方法浅复制a >>> c array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) # 此时c的数据与a一样 >>> c is a false >>> c.base is a # base属性可以告诉我们是否有视图或原始数组。 false >>> c.flags.owndata # ndarray.flags 有关数组内存分布的信息。 false >>> c.shape = 2,6 >>> a.shape (3, 4) >>> c[0,4]=123 >>> a array([[ 0, 1, 2, 3], [123, 5, 6, 7], [ 8, 9, 10, 11]]) >>> x = a[:,1:3] >>> x[:] array([[ 1, 2], [ 5, 6], [ 9, 10]]) >>> a array([[ 0, 1, 2, 3], [123, 5, 6, 7], [ 8, 9, 10, 11]]) >>> x[:] = 10 >>> a array([[ 0, 10, 10, 3], [123, 10, 10, 7], [ 8, 10, 10, 11]])
- 深拷贝
- 在numpy中可以通过copy方法生成数组以及其数据的完整拷贝,即深拷贝
- demo
>>> d=a.copy() >>> d array([[ 0, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]]) >>> d is a false >>> d.base is a false >>> d[0,0] = 999 >>> d array([[ 999, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]]) >>> a array([[ 0, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]])