目录
视图(View)
浅拷贝(Shallow Copy)
深拷贝(Deep Copy)
混合浅拷贝和深拷贝
总结
在 Python 中,拷贝有两种类型:浅拷贝(shallow copy)和深拷贝(deep copy)。在 NumPy 中,这些概念也适用,并且还有视图的概念。
视图是数组和其数据的另一个接口。在 NumPy 中,您可以通过切片操作创建一个数组的视图。视图仅仅是原始数组数据的一个新视角,任何对视图的修改都会反映到原始数组上,反之亦然。
创建视图
import numpy as np
# 创建原始数组
arr = np.array([1, 2, 3, 4, 5])
print("Original array:", arr)
# 切片创建视图
arr_view = arr[1:4]
print("View of the array:", arr_view)
修改视图,原始数组也会改变:
# 修改视图
arr_view[1] = 20
print("Modified view:", arr_view)
print("Original array after modification:", arr)
预期输出:
riginal array: [1 2 3 4 5]
View of the array: [2 3 4]
Modified view: [ 2 20 4]
Original array after modification: [ 1 2 20 4 5]
浅拷贝创建一个新对象,但不会创建原始对象中嵌套对象的副本。在 NumPy 中,视图经常被当成浅拷贝的一种,因为它们共享同一数据块。
创建浅拷贝,在 NumPy 中创建浅拷贝,通常通过视图进行:
# 浅拷贝创建视图
arr_shallow_copy = arr_view
深拷贝创建一个新对象以及其包含的所有嵌套对象的副本。在 NumPy 中,可以使用 copy
方法来创建一个数组的深拷贝,这样生成的数组与原始数组完全独立。
创建深拷贝
# 使用 copy 方法创建深拷贝
arr_deep_copy = arr.copy()
# 修改深拷贝
arr_deep_copy[0] = 100
print("Deep copy of the array:", arr_deep_copy)
print("Original array remains unchanged:", arr)
输出:
Deep copy of the array: [100 2 20 4 5]
Original array remains unchanged: [ 1 2 20 4 5]
这里的 arr_deep_copy
是原始数组 arr
的完整副本,修改 arr_deep_copy
不会影响 arr
。
在 NumPy 中,如果数组包含其他数组(即嵌套数组),则浅拷贝和深拷贝的行为会有所不同。深拷贝(copy
方法)会创建所有层级的副本。
# 创建包含嵌套数组的数组
arr_with_nested = np.array([np.array([1, 2]), np.array([3, 4])])
# 浅拷贝
shallow_copy_nested = arr_with_nested.copy()
# 深拷贝
deep_copy_nested = np.array([sub_arr.copy() for sub_arr in arr_with_nested])
# 修改原始嵌套数组中的一个子数组
arr_with_nested[0][0] = 99
print("Original array with nested arrays:", arr_with_nested)
# 检查浅拷贝和深拷贝
print("Shallow copy after modification:", shallow_copy_nested)
print("Deep copy remains unchanged:", deep_copy_nested)
输出:
riginal array with nested arrays: [array([99, 2]) array([3, 4])]
Shallow copy after modification: [array([99, 2]) array([3, 4])]
Deep copy remains unchanged: [array([1, 2]) array([3, 4])]
在这个例子中,浅拷贝 shallow_copy_nested
显示了对原始嵌套数组的修改,而深拷贝 deep_copy_nested
保持不变,因为它创建了嵌套数组的独立副本。
NumPy 中的视图、浅拷贝和深拷贝提供了不同级别的数据复制和引用机制。视图(类似于浅拷贝)允许您在不复制数据的情况下,对数组的子集进行操作;而深拷贝确保原始数据的完整独立性,允许您在保留原始数据的同时进行操作。