一. 什么是视图和副本
- 视图:可理解为原有数据的一个别称或引用(但是这个引用和赋值产生的引用不同),通过该别称或引用便可访问、操作原有数据,但原有数据不会产生拷贝,所以对于视图的修改会反映到原数据中,类似于Java的浅拷贝。
- 副本:数据的一个完整的拷贝,修改副本不会影响原数据,类似于Java中的深拷贝。
二. 何时出现视图,何时出现副本
视图一般发生在:
- numpy的切片操作返回原数据的视图
- 调用ndarray的view()函数产生一个视图
副本一般发生在:
- Python序列的切片操作
- 调用ndarray的copy()函数产生一个副本
三. 具体看几个栗子
1. 完全不发生拷贝
这种情况一般发生在赋值操作中。看下面这个栗子,两个变量a,b都指向同一块内存区域,id相同,完全没有发生拷贝。
a=[1,2,3,4]
b=a
print(id(a),id(b))
Out:
196674184 196674184
2. 发生视图的情况
Numpy的切片操作会返回原数据的视图,变量a,b都是arr的一部分视图,对视图的修改会直接反映到原数据中。但是我们观察a,b的id,他们是不同的,也就是说,视图虽然指向原数据,但是他们和赋值引用还是有区别的。
arr=np.arange(12)
print(arr)
a=arr[3:]
b=arr[3:]
a[1]=123
b[2]=234
print(arr)
print(id(a),id(b),id(arr[3:]))
Out:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
[ 0 1 2 3 123 234 6 7 8 9 10 11]
196727792 196728512 196728192
3. 发生副本的情况
Python序列的切片会 返回一个副本,修改副本对原数据不影响。
arr=[1,2,3,4,5]
a=arr[1:]
a[3]=111
print(arr,a)
Out:
[1, 2, 3, 4, 5] [2, 3, 4, 111]
网友评论