在操作数组的时候,它们的数据有时候拷贝进一个新的数组,有时候又不是。
不拷贝
:
如果只是简单的赋值,那么不会进行拷贝:
a = np.arange(12)
b = a # 这种情况不会进行拷贝
print(b is a) # 返回True,说明b和a是相同的
栈区与堆区
的区别:
栈区内存空间小,但是运行效率高;堆区内存空间大,但是运行效率低。
View或者浅拷贝
:
有些情况,会进行变量的拷贝,但是他们所指向的内存空间都是一样的,那么这种情况叫做浅拷贝,或者叫做View(视图)
:
a = np.arange(12)
c = a.view()
print(c is a) # 返回False,说明c和a是两个不同变量
c[0] = 100
print(a[0]) # 打印100,说明对c上的改变,会影响a上面的值,它们指向的堆区内存空间还是一样的,这样叫做浅拷贝
图示
:
深拷贝
:
将之前数据完整的拷贝一份放到另外一块堆区内存空间中,这样就是两个完全不同的值了:
a = np.arange(12)
d = a.copy()
print(d is a) # 返回False,说明d和a是两个不同的变量
d[0] = 100
print(a[0]) # 打印0,说明d和a指向的内存空间完全不同了
图示
:
示例
:
例如本系列之前讲到的,flatten
和ravel
就是这种情况,ravel
返回就是View
,而flatten
返回的就是深拷贝。
ravel
:
a1 = np.random.rand(2,4)
a1
# result:
array([[0.27536253, 0.31079 , 0.04965446, 0.90008811],
[0.29087712, 0.12152324, 0.975831 , 0.03759279]])
a2 = a1.ravel()
a2[0] = 0
a2,a1 # 修改了a1的值,说明ravel返回的是一个浅拷贝
# result:
(array([0. , 0.31079 , 0.04965446, 0.90008811, 0.29087712,
0.12152324, 0.975831 , 0.03759279]),
array([[0. , 0.31079 , 0.04965446, 0.90008811],
[0.29087712, 0.12152324, 0.975831 , 0.03759279]]))
flatten
:
a3 = a1.flatten()
a3[1] = 100
a3,a1
# result:
(array([0.00000000e+00, 1.00000000e+02, 4.96544581e-02, 9.00088115e-01,
2.90877116e-01, 1.21523243e-01, 9.75830998e-01, 3.75927942e-02]),
array([[0. , 0.31079 , 0.04965446, 0.90008811],
[0.29087712, 0.12152324, 0.975831 , 0.03759279]]))
Summary
:
在数组操作中分成三种拷贝: