HOWTO · Python

在 Python 中复制二维数组

本文演示如何在 Python 中制作二维数组的副本

本页内容

在 Python 中复制二维数据时,应根据数据类型和是否共享数据来选择操作:NumPy 数组需要独立数据时使用 copy();嵌套列表的内层列表也需要彼此独立时使用 copy.deepcopy();若有意共享内层对象,则使用浅拷贝。NumPy 的 view() 会创建一个不同的数组对象,但仍与原数组共享底层数据。

二维数组按行和列组织值。对于由列表组成的 Python 列表,每个内层列表表示一行;两个索引依次选取某一行及该行中的元素,例如 data[row_index][column_index]。

使用 NumPy 的 copy() 方法创建二维数组副本

对于 NumPy ndarray,调用它的 copy() 方法可创建一个拥有独立数据的数组。下面的示例修改副本中的一个值,然后查看两个数组:

import numpy as np

original = np.array([[23, 34, 45], [24, 45, 78]])
copied = original.copy()
copied[0, 2] = 65

print("Copy:", copied.tolist())
print("Original:", original.tolist())
Copy: [[23, 34, 65], [24, 45, 78]]
Original: [[23, 34, 45], [24, 45, 78]]

赋值会修改 copied,而原数组保留初始值。若需要独立编辑数值数组数据,这是直接的选择。示例中的代码和输出标签保持英文原样。NumPy 数组也可以包含 Python 对象;复制对象类型数组时会复制数组的数据缓冲区,但不会递归复制其中存储的 Python 对象。

使用 copy.deepcopy() 函数创建二维数组副本

对于嵌套的 Python 列表,copy.deepcopy() 会递归复制列表及其内容。如果复制后可能修改某个内层列表,这一点就很重要:

import copy

original = [["red", "blue"], ["green", "gold"]]
copied = copy.deepcopy(original)
copied[0].append("white")

print("Copy:", copied)
print("Original:", original)
Copy: [['red', 'blue', 'white'], ['green', 'gold']]
Original: [['red', 'blue'], ['green', 'gold']]

新的外层列表及其内层列表都与原列表分开,因此向 copied 中的内层列表追加元素不会改变 original。对于嵌套的可变数据,deepcopy() 很有用;处理大型对象或自定义对象时,应考虑递归复制所有引用对象是否合适。示例中的代码和输出标签保持英文原样。

在 Python 中创建二维数组的浅拷贝

浅拷贝会创建一个新的外层容器,同时保留对原对象内层对象的引用。对于嵌套列表,copy.copy() 和外层列表的 list.copy() 方法都会这样处理:

import copy

original = [["red", "blue"], ["green", "gold"]]
copied = copy.copy(original)
copied[0].append("white")

print("Copy:", copied)
print("Original:", original)
Copy: [['red', 'blue', 'white'], ['green', 'gold']]
Original: [['red', 'blue', 'white'], ['green', 'gold']]

这里两个外层列表都引用同一个首个内层列表,因此追加元素后,两边都会显示这一变化。替换副本外层列表中的某个元素,例如 copied[0] = ["black"],只会改变该外层列表中的引用。如果也需要独立的内层列表,请使用 copy.deepcopy()。示例中的代码和输出标签保持英文原样。

NumPy 的 view() 与嵌套 Python 列表的浅拷贝是不同的操作。它会返回一个不同的 ndarray 对象,但与原数组共享数据,因此通过视图赋值也会改变原数组所见的值。若需要独立的 NumPy 数据,请改用 ndarray.copy()。对象身份与数据共享是两个不同的问题:两个数组可以是不同对象,却仍呈现相同的底层数据。

import numpy as np

original = np.array([[24, 23, 25], [32, 43, 54]])
view = original.view()
view[0, 2] = 100

print("View:", view.tolist())
print("Original:", original.tolist())
View: [[24, 23, 100], [32, 43, 54]]
Original: [[24, 23, 100], [32, 43, 54]]