在执行函数时,其中一些返回输入数组的副本,而另一些返回视图。 当内容物理存储在另一个位置时,称为副本。 另一方面,如果提供了相同内存内容的不同视图,我们将其称为视图。
简单的赋值不会创建数组对象的副本。 相反,它使用原始数组的相同id()
来访问它。 id()
返回 Python 对象的通用标识符,类似于 C 中的指针。
此外,一个数组的任何变化都反映在另一个数组上。 例如,一个数组的形状改变也会改变另一个数组的形状。
import numpy as np a = np.arange(6) print '我们的数组是:' print a print '调用 id() 函数:' print id(a) print 'a 赋值给 b:' b = a print b print 'b 拥有相同 id():' print id(b) print '修改 b 的形状:' b.shape = 3,2 print b print 'a 的形状也修改了:' print a
输出如下:
我们的数组是: [0 1 2 3 4 5] 调用 id() 函数: a 赋值给 b: [0 1 2 3 4 5] b 拥有相同 id(): 修改 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 '数组 a:' print a print '创建 a 的视图:' b = a.view() print b print '两个数组的 id() 不同:' print 'a 的 id():' print id(a) print 'b 的 id():' print id(b) # 修改 b 的形状,并不会修改 a b.shape = 2,3 print 'b 的形状:' print b print 'a 的形状:' print a
输出如下:
数组 a: [[0 1] [2 3] [4 5]] 创建 a 的视图: [[0 1] [2 3] [4 5]] 两个数组的 id() 不同: a 的 id(): b 的 id(): 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 '我们的数组:' print a print '创建切片:' 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 '数组 a:' print a print '创建 a 的深层副本:' b = a.copy() print '数组 b:' print b # b 与 a 不共享任何内容 print '我们能够写入 b 来写入 a 吗?' print b is a print '修改 b 的内容:' b[0,0] = 100 print '修改后的数组 b:' print b print 'a 保持不变:' 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]]