从另一个项目中复制一个项目是一个谨慎的操作,如果执行得不好,那么它就会产生后果。在编程中,你不仅仅是在复制数值,有时你也在复制引用。让我们看看如何在Python中复制一个数组。
Python数组复制
要在Python中复制一个数组,使用赋值运算符(=)。但是还有两种方法可以用来复制数组:
- 浅层拷贝
- 深拷贝
在Python中,赋值运算符并不复制对象。相反,它在一个目标和一个对象之间建立绑定。当我们使用 = 操作符时,我们认为它创建了一个新的对象,但它并没有。它只是创建了一个新的变量,共享原始对象的引用。
为了说明这一点,让我们举个例子,看看我在说什么:
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Printing the id of the array
print(id(arr))
# Using assignment operator to copy array
arr2 = arr
# Printing the id of the copied array
print(id(arr2))
# Changing the original array
arr[2] = 11
# Printing both arrays
print(arr)
print(arr2)
输出
4365624976
4365624976
[ 1 2 11 4 5]
[ 1 2 11 4 5]
你可以看到,我们从arr中复制了arr2 ,但是两个数组对象共享同一个引用。所以当你修改原始数组的时候,这个变化也会应用于复制的数组。所以,如果你改变了arr,arr2也会改变。
现在,让我们来谈谈Python中的浅层和深层拷贝。
Python中的浅拷贝
一个浅拷贝是对象的一个位数拷贝 。它的意思是,当一个新的对象在原始对象的基础上被创建时,它有一个原始对象中数值的精确拷贝。如果对象的任何一个值是对其他对象的引用,只是引用地址被复制。
复制过程并不创建子对象本身的副本。但是,在一个对象的浅层拷贝的情况下,该对象的引用被复制到另一个对象。这意味着对对象的副本所做的任何改变都会反映在原始对象中。
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Printing the id of the array
print(id(arr))
# Shallow copy to copy array
arr2 = arr.view()
# Printing the id of the copied array
print(id(arr2))
# Changing the original array
arr[2] = 11
# Printing both arrays
print(arr)
print(arr2)
输出
4378519184
4378519280
[ 1 2 11 4 5]
[ 1 2 11 4 5]
你可以看到,两个数组引用了不同的对象,这意味着改变值;另一个数组的值也会改变。
让我们来看看Python中的深度拷贝。
Python中的深度拷贝
深度复制是一个过程,其中复制过程是递归发生的。它意味着首先创建一个新的对象,然后用在原始对象中发现的子对象的副本来递归地填充它。在深度复制的情况下,对象的副本被复制到其他对象中。
因此,当你复制一个对象时,被复制的数组的值的变化并不反映原始数组的情况。
要在Python中创建一个数组的深度拷贝,使用array.copy()方法。array.copy()方法不需要任何参数,因为它是在原始数组上调用的,并返回深度复制的数组。
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Printing the id of the array
print(id(arr))
# Deep copy using copy() method
arr2 = arr.copy()
# Printing the id of the copied array
print(id(arr2))
# Changing the original array
arr[2] = 11
# Printing both arrays
print(arr)
print(arr2)
输出
4301858448
4301858544
[ 1 2 11 4 5]
[1 2 3 4 5]
现在你可以看到,被复制的数组的值的变化并没有反映在原始数组上。现在的值和引用都完全不同,这被称为数组的深度拷贝。
当你把一个数组复制到另一个数组时,大多数情况下,请使用copy()方法,因为它使用深度拷贝来复制数组;否则,你会得到不想要的结果。
结论
要在Python中创建一个数组的深度拷贝,请使用numpy API中提供的array.copy()方法。要创建一个数组的浅层拷贝,请使用array.view()方法。否则,你可以通过使用一个简单的赋值运算符来创建一个对象的副本。
本教程就到此为止。