形态操作
一、改变阵列形态
阵列的形态是由每个轴上的所含元素决定的:
>>> a = np.floor(10 * rg.random((3, 4))) # 取整,生成 0 - 9 之间的随机整数
>>> a
array([[3., 7., 3., 4.],
[1., 4., 2., 2.],
[7., 2., 4., 9.]])
>>> a.shape
(3, 4)
Numpy有很多种方法改变一个阵列的形态,下面三种方法可以改变阵列陈列并返回改变后的阵列,但是都不会对原阵列进行操作。
- narray对象内置的方法:ravel,返回一个一维阵列
- narray对象内置的方法:reshape,按照传入元组进行塑形,要求传入的元组尺寸可容纳的元素个数和原阵列相等
- Numpy内置方法:transpose。也就是矩阵转置,可以简写为:A.T
# ravel最左侧维度优先
>>> a.ravel() # returns the array, flattened
array([3., 7., 3., 4., 1., 4., 2., 2., 7., 2., 4., 9.])
# 使用reshape 或 ravel 时,可以传入FORTRAN-style参数,来使最右侧维度优先
>>> a.reshape(6, 2) # returns the array with a modified shape
array([[3., 7.],
[3., 4.],
[1., 4.],
[2., 2.],
[7., 2.],
[4., 9.]])
# resize方法直接作用于原阵列,而这三种方法不会改变原阵列
>>> a
array([[3., 7., 3., 4.],
[1., 4., 2., 2.],
[7., 2., 4., 9.]])
>>> a.resize((2, 6))
>>> a
array([[3., 7., 3., 4., 1., 4.],
[2., 2., 7., 2., 4., 9.]])
# 若reshape调用时传入了 -1, 则会对其他维度进行自适应计算:
>>> a.reshape(3, -1)
array([[3., 7., 3., 4.],
[1., 4., 2., 2.],
[7., 2., 4., 9.]])
>>> a.T # returns the array, transposed
array([[3., 1., 7.],
[7., 4., 2.],
[3., 2., 4.],
[4., 2., 9.]])
>>> a.T.shape
(4, 3)
>>> a.shape
(3, 4)
-
其他版块:
二、合并不同阵列
一些阵列可以以不同轴(例如二维阵列的:横、纵)进行合并。这些合并是不会改变维度的,namely,两个二维阵列合并完还是二维阵列。
>>> a = np.floor(10 * rg.random((2, 2)))
>>> a
array([[9., 7.],
[5., 2.]])
>>> b = np.floor(10 * rg.random((2, 2)))
>>> b
array([[1., 9.],
[5., 1.]])
>>> np.vstack((a, b)) # 纵向合并
array([[9., 7.],
[5., 2.],
[1., 9.],
[5., 1.]])
>>> np.hstack((a, b)) # 横向合并
array([[9., 7., 1., 9.],
[5., 2., 5., 1.]])
column_stack这个函数可以按列拼接,将一维阵列堆叠成二维阵列。对列进行升维。若是对二维阵列调用此函数,则效果和 hstack 等同。
>>> from numpy import newaxis
>>> np.column_stack((a, b)) # with 2D arrays 等同于hstack
array([[9., 7., 1., 9.],
[5., 2., 5., 1.]])
>>> a = np.array([4., 2.])
>>> b = np.array([3., 8.])
>>> np.column_stack((a, b)) # returns a 2D array 会增添维度
array([[4., 3.],
[2., 8.]])
>>> np.hstack((a, b)) # the result is different ,不会改变维度
array([4., 2., 3., 8.])
#保持第一维不变,增添第二维:列
>>> a[:, newaxis] # view `a` as a 2D column vector
array([[4.],
[2.]])
# 合并升维之后的两个一维阵列,返回一个二维阵列;在二维阵列上的 column_stack 等同于 hstack
>>> np.column_stack((a[:, newaxis], b[:, newaxis]))
array([[4., 3.],
[2., 8.]])
>>> np.hstack((a[:, newaxis], b[:, newaxis])) # the result is the same
array([[4., 3.],
[2., 8.]])
另外,row_stack函数对任何输入阵列的作用效果都等同于vstack函数。其实,row stack 是 vstack 的别名:
>>> np.column_stack is np.hstack
False
# row_stack不会进行升维
>>> np.row_stack is np.vstack
True
一般来说,对于多于两个维度的数组,hstack 堆栈沿着第二个轴,vstack 堆栈沿着第一个轴,并且concatenate函数允许一个可选参数给出连接应该发生的轴的数目。
另外,在一些复杂的例子中,可以使用np内置的r_和c_函数来构造阵列,注意他们的调用方式,直接使用[]而不需():
# 按行构建阵列
>>> np.r_[1:4, 0, 4] # 参数依次为 构建列表, 下标表达式
array([1, 2, 3, 0, 4])
>>> np.c_[np.array([1,2,3]), np.array([4,5,6])]
array([[1, 4],
[2, 5],
[3, 6]])
np.c_[np.array([[1,2,3]]), 0, 0, np.array([[4,5,6]])]
array([[1, 2, 3, ..., 4, 5, 6]])
三、分化阵列
使用hsplit函数可以将阵列分割水平的对应的 n 个阵列。
>>> a = np.floor(10 * rg.random((2, 12)))
>>> a
array([[6., 7., 6., 9., 0., 5., 4., 0., 6., 8., 5., 2.],
[8., 5., 5., 7., 1., 8., 6., 7., 1., 8., 1., 0.]])
>>> # Split `a` into 3
>>> np.hsplit(a, 3)
# 将 a 分割横轴成为 3 个阵列
[array([[6., 7., 6., 9.],
[8., 5., 5., 7.]]), array([[0., 5., 4., 0.],
[1., 8., 6., 7.]]), array([[6., 8., 5., 2.],
[1., 8., 1., 0.]])]
>>> # Split `a` after the third and the fourth column
>>> np.hsplit(a, (3, 4)) # 按照第 n 列进行切割
[array([[6., 7., 6.],
[8., 5., 5.]]), array([[9.],
[7.]]), array([[0., 5., 4., 0., 6., 8., 5., 2.],
[1., 8., 6., 7., 1., 8., 1., 0.]])]
vsplit函数允许你切割纵轴,array_split函数允许你自定义切割轴。