NumPy库---拷贝

NumPy库—拷贝

在操作数组的时候,它们的数据有时候拷贝进一个新的数组,有时候又不是。
不拷贝
如果只是简单的赋值,那么不会进行拷贝:

a = np.arange(12)
b = a # 这种情况不会进行拷贝
print(b is a) # 返回True,说明b和a是相同的

栈区与堆区的区别:
栈区内存空间小,但是运行效率高;堆区内存空间大,但是运行效率低。

a与b共享同一段栈区NumPy库---拷贝_第1张图片

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与c占用两段不同的栈区,共享一段堆区内存空间
NumPy库---拷贝_第2张图片

深拷贝
将之前数据完整的拷贝一份放到另外一块堆区内存空间中,这样就是两个完全不同的值了:

a = np.arange(12)
d = a.copy()
print(d is a) # 返回False,说明d和a是两个不同的变量
d[0] = 100
print(a[0]) # 打印0,说明d和a指向的内存空间完全不同了

图示

d 与 a共享两段栈区内存空间,并且占用不同的堆区内存空间NumPy库---拷贝_第3张图片

示例
例如本系列之前讲到的,flattenravel就是这种情况,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
在数组操作中分成三种拷贝:

  1. 不拷贝:直接赋值,那么栈区没有拷贝,只是用同一个栈区定义了不同的名称。
  2. 浅拷贝:只拷贝栈区,栈区指定的堆区并没有拷贝
  3. 深拷贝:栈区和堆区都拷贝了

你可能感兴趣的:(数据分析,python,数据分析)