NumPy - 副本和视图
在执行函数时,其中一些返回输入数组的副本,而另一些返回视图。 当内容物理存储在另一个位置时,称为副本。 另一方面,如果提供了相同内存内容的不同视图,我们将其称为视图。
无复制
简单的赋值不会创建数组对象的副本。 相反,它使用原始数组的相同id()
来访问它。 id()
返回 Python 对象的通用标识符,类似于 C 中的指针。
此外,一个数组的任何变化都反映在另一个数组上。 例如,一个数组的形状改变也会改变另一个数组的形状。
示例
import numpy as np
a = np.arange(6)
print &apos我们的数组是:&apos
print a
print &apos调用 id() 函数:&apos
print id(a)
print &aposa 赋值给 b:&apos
b = a
print b
print &aposb 拥有相同 id():&apos
print id(b)
print &apos修改 b 的形状:&apos
b.shape = 3,2
print b
print &aposa 的形状也修改了:&apos
print a
输出如下:
我们的数组是:
[0 1 2 3 4 5]
调用 id() 函数:
139747815479536
a 赋值给 b:
[0 1 2 3 4 5]
b 拥有相同 id():
139747815479536
修改 b 的形状:
[[0 1]
[2 3]
[4 5]]
a 的形状也修改了:
[[0 1]
[2 3]
[4 5]]
视图或浅复制
NumPy 拥有ndarray.view()
方法,它是一个新的数组对象,并可查看原始数组的相同数据。 与前一种情况不同,新数组的维数更改不会更改原始数据的维数。
示例
import numpy as np
# 最开始 a 是个 3X2 的数组
a = np.arange(6).reshape(3,2)
print &apos数组 a:&apos
print a
print &apos创建 a 的视图:&apos
b = a.view()
print b
print &apos两个数组的 id() 不同:&apos
print &aposa 的 id():&apos
print id(a)
print &aposb 的 id():&apos
print id(b)
# 修改 b 的形状,并不会修改 a
b.shape = 2,3
print &aposb 的形状:&apos
print b
print &aposa 的形状:&apos
print a
输出如下:
数组 a:
[[0 1]
[2 3]
[4 5]]
创建 a 的视图:
[[0 1]
[2 3]
[4 5]]
两个数组的 id() 不同:
a 的 id():
140424307227264
b 的 id():
140424151696288
b 的形状:
[[0 1 2]
[3 4 5]]
a 的形状:
[[0 1]
[2 3]
[4 5]]
数组的切片也会创建视图:
示例
import numpy as np
a = np.array([[10,10], [2,3], [4,5]])
print &apos我们的数组:&apos
print a
print &apos创建切片:&apos
s = a[:, :2]
print s
输出如下:
我们的数组:
[[10 10]
[ 2 3]
[ 4 5]]
创建切片:
[[10 10]
[ 2 3]
[ 4 5]]
深复制
ndarray.copy()
函数创建一个深层副本。 它是数组及其数据的完整副本,不与原始数组共享。
示例
import numpy as np
a = np.array([[10,10], [2,3], [4,5]])
print &apos数组 a:&apos
print a
print &apos创建 a 的深层副本:&apos
b = a.copy()
print &apos数组 b:&apos
print b
# b 与 a 不共享任何内容
print &apos我们能够写入 b 来写入 a 吗?&apos
print b is a
print &apos修改 b 的内容:&apos
b[0,0] = 100
print &apos修改后的数组 b:&apos
print b
print &aposa 保持不变:&apos
print a
输出如下:
数组 a:
[[10 10]
[ 2 3]
[ 4 5]]
创建 a 的深层副本:
数组 b:
[[10 10]
[ 2 3]
[ 4 5]]
我们能够写入 b 来写入 a 吗?
False
修改 b 的内容:
修改后的数组 b:
[[100 10]
[ 2 3]
[ 4 5]]
a 保持不变:
[[10 10]
[ 2 3]
[ 4 5]]