NumPy 是一个为 Python 提供高性能向量、矩阵和高维数据结构的科学计算库。它通过 C 和 Fortran 实现,因此用向量和矩阵建立方程并实现数值计算有非常好的性能。NumPy 基本上是所有使用 Python 进行数值计算的框架和包的基础,例如 TensorFlow 和 PyTorch,构建机器学习模型最基础的内容就是学会使用 NumPy 搭建计算过程。
拆分数组
使用 hsplit 可以顺着水平轴拆分一个数组,我们指定切分后输出的数组数,或指定在哪一列拆分数组:
代码语言:javascript复制>>> a = np.floor(10*np.random.random((2,12)))
>>> a
array([[ 9., 5., 6., 3., 6., 8., 0., 7., 9., 7., 2., 7.],
[ 1., 4., 9., 2., 2., 1., 0., 6., 2., 2., 4., 0.]])
>>> np.hsplit(a,3) # Split a into 3
[array([[ 9., 5., 6., 3.],
[ 1., 4., 9., 2.]]), array([[ 6., 8., 0., 7.],
[ 2., 1., 0., 6.]]), array([[ 9., 7., 2., 7.],
[ 2., 2., 4., 0.]])]
>>> np.hsplit(a,(3,4)) # Split a after the third and the fourth column
[array([[ 9., 5., 6.],
[ 1., 4., 9.]]), array([[ 3.],
[ 2.]]), array([[ 6., 8., 0., 7., 9., 7., 2., 7.],
[ 2., 1., 0., 6., 2., 2., 4., 0.]])]
vsplit 沿着垂直轴拆分,array_split 可指定顺着哪一条轴拆分。
复制与 views
在进行数组运算或操作时,入门者经常很难判断数据到底是复制到了新的数组还是直接在原始数据上修改。这对进一步的运算有很大的影响,因此有时候我们也需要复制内容到新的变量内存中,而不能仅将新变量指向原内存。目前一般有三种复制方法,即不复制内存、浅复制以及深复制。
实际不复制
简单的任务并不会复制数组目标或它们的数据,如下先把变量 a 赋值于 b,然后修改变量 b 就会同时修改变量 a,这种一般的赋值方法会令变量间具有关联性。
代码语言:javascript复制>>> a = np.arange(12)
>>> b = a # no new object is created
>>> b is a # a and b are two names for the same ndarray object
True
>>> b.shape = 3,4 # changes the shape of a
>>> a.shape
(3, 4)
Python 将不定对象作为参照(references)传递,所以调用函数不会产生目标识别符的变化,也不会发生实际的内容复制。
代码语言:javascript复制>>> def f(x):
... print(id(x))
...
>>> id(a) # id is a unique identifier of an object
148293216
>>> f(a)
148293216
View 或浅复制
不同数组对象可以共享相同数据,view 方法可以创建一个新数组对象来查看相同数据。如下 c 和 a 的目标识别符并不一致,且改变其中一个变量的 shape 并不会对应改变另一个。但这两个数组是共享所有元素的,所以改变一个数组的某个元素同样会改变另一个数组的对应元素。
代码语言:javascript复制>>> c = a.view()
>>> c is a
False
>>> c.base is a # c is a view of the data owned by a
True
>>> c.flags.owndata
False
>>>
>>> c.shape = 2,6 # a s shape doesn t change
>>> a.shape
(3, 4)
>>> c[0,4] = 1234 # a s data changes
>>> a
array([[ 0, 1, 2, 3],
[1234, 5, 6, 7],
[ 8, 9, 10, 11]])
分割数组输出的是它的一个 view,如下将数组 a 分割为子数组 s,那么 s 就是 a 的一个 view,修改 s 中的元素同样会修改 a 中对应的元素。
代码语言:javascript复制>>> s = a[ : , 1:3] # spaces added for clarity; could also be written "s = a[:,1:3]"
>>> s[:] = 10 # s[:] is a view of s. Note the difference between s=10 and s[:]=10
>>> a
array([[ 0, 10, 10, 3],
[1234, 10, 10, 7],
[ 8, 10, 10, 11]])
深复制
copy 方法可完整地复制数组及数据,这种赋值方法会令两个变量有不一样的数组目标,且数据不共享。
代码语言:javascript复制>>> d = a.copy() # a new array object with new data is created
>>> d is a
False
>>> d.base is a # d doesn t share anything with a
False
>>> d[0,0] = 9999
>>> a
array([[ 0, 10, 10, 3],
[1234, 10, 10, 7],
[ 8, 10, 10, 11]])