np.hstack(), np.concatenate()与np.stack()解析

np.hstack(),np.concatenate()与np.stack()是numpy中实现数组拼接的三个函数。
1. np.hsatck(arrays)
np.hstack(arrays)是其中最简单的一个函数。
它接收的参数是一个元组,包含需要组合在一起的几个数组。这些数组需要满足的要求是

  • 维数相同
  • 零轴元素个数相同

例:

a = np.arange(9).reshape(3, 3)
print('a:\n', a)
b = np.arange(12).reshape(3, 4)
print('b:\n', b)
c = np.arange(15).reshape(3, 5)
print('c:\n', c)
print('ab:\n', np.hstack((a, b)))
print('abc:\n', np.hstack((a, b, c)))

输出:

a:
 [[0 1 2]
 [3 4 5]
 [6 7 8]]
b:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
c:
 [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
ab:
 [[ 0  1  2  0  1  2  3]
 [ 3  4  5  4  5  6  7]
 [ 6  7  8  8  9 10 11]]
abc:
 [[ 0  1  2  0  1  2  3  0  1  2  3  4]
 [ 3  4  5  4  5  6  7  5  6  7  8  9]
 [ 6  7  8  8  9 10 11 10 11 12 13 14]]

这个例子相信大家一看就懂,不做赘述。

2. np.concatenate(arrays, axis=0, out=None)
这个函数相当于np.hstack()的扩展。
它接收三个参数:

  • arrays是一个元组,包含需要组合的几个数组,这些数组需要满足的要求是:
    • 维数相同
    • 除axis指定维度外其余维度元素个数对应相等
  • aixs是维度,指定数组组合的方向,默认为零轴方向(即垂直组合)
  • out(可选参数)是一个多维数组,如果提供该参数,函数返回结果将会保存在out中,当然,out的shape需要与结果相等

例:

a = np.arange(8).reshape(2, 2, 2)
b = np.arange(12).reshape(2, 2, 3)
c = np.arange(18).reshape(2, 3, 3)

我们创建了三个数组a,b,c。a和b除2轴外其余维度对应相等,因此a和b可以在2轴方向组合。b和c除1轴外其余维度对应相等,因此a和b可以在1轴方向组合(即水平组合,np.concatenate((a,b),axis=1)与np.hstack((a,b))的效果是等同的)

组合a,b

d = np.concatenate((a, b), axis=2)
print(d, '\n\nshape:', d.shape)

输出:

[[[ 0  1  0  1  2]
  [ 2  3  3  4  5]]

 [[ 4  5  6  7  8]
  [ 6  7  9 10 11]]] 

shape: (2, 2, 5)

组合b,c`

e = np.concatenate((b, c), axis=1)
print(e, '\n\nshape:', e.shape)

输出

[[[ 0  1  2]
  [ 3  4  5]
  [ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]]

 [[ 6  7  8]
  [ 9 10 11]
  [ 9 10 11]
  [12 13 14]
  [15 16 17]]] 

shape: (2, 5, 3)

由此可以看出,将多个数组在指定轴上组合后,结果数组除指定轴以外,其余维度元素个数不变,指定轴元素个数为所有参数数组在该轴上元素个数的和。例如,将shape为(2,2,3)的数组与shape为(2,3,3)的数组在1轴方向上组合,结果数组的shape即为(2,2+3,3)。

3. np.stack(arrays, axis=0, out=None)
这是3个函数中最难理解的一个函数。
它接收3个参数:

    • arrays是一个元组,包含需要组合的几个数组,这些数组需要满足的要求是:
    • 维数相同
    • 各维度元素个数对应相等(即形状相等)
  • aixs是维度,指定数组增加哪个维度,以及组合的方向。默认增加零轴,并按照零轴方向组合。
  • out(可选参数)是一个多维数组,如果提供该参数,函数返回结果将会保存在out中,当然,out的shape需要与结果相等

对于axis参数所指定的内容似乎比较难以理解,但是根据解释,已经可以看到我把这个函数的功能分为了两步:

  • 在axis指定轴上增加一维
  • 在axis指定轴方向上组合数组

我们先来看一个例子(A):

a = np.arange(9).reshape(3, 3)
m = a*3
b = np.stack((a, m), axis=1)
print(b, '\n\n', b.shape)

输出:
[[[ 0  1  2]
  [ 0  3  6]]

 [[ 3  4  5]
  [ 9 12 15]]

 [[ 6  7  8]
  [18 21 24]]] 

 (3, 2, 3)

这个变化如何实现的?
我们就按照上面说的两个步骤来分解。
首先,对于每个数组,在axis指定轴上增加一维。为了模拟这一步,可以对单个数组进行stack操作。

a = np.arange(9).reshape(3, 3)
m = a
b = np.stack((a,), axis=1)
print(b, '\n\n', b.shape)

输出:
[[[0 1 2]]

 [[3 4 5]]

 [[6 7 8]]] 

 (3, 1, 3)

可以看到,在一个shape为(3,3)的数组的1轴上增加一维,其shape就变为(3,1,3),以此类推,如果在一个shape为(3,3)的数组的0轴上增加一维,其shape就变为(1,3,3), 验证一下:

a = np.arange(9).reshape(3, 3)
m = a
b = np.stack((a,), axis=0)
print(b, '\n\n', b.shape)

输出:
[[[0 1 2]
  [3 4 5]
  [6 7 8]]] 

 (1, 3, 3)

符合推测。

接着,我们做第二步,在axis指定轴方向上组合数组,这就是concatenate()函数提供的功能。
因此我们可以通过下述操作实现例(A)的等价变换。即:分别再数组a和m的一轴上增加一维,然后让他们在一轴上组合起来。

a = np.arange(9).reshape(3, 3)
m = a*3
b = np.stack((a,), axis=1)
c = np.stack((m,), axis=1)
d = np.concatenate((b,c), axis=1)
print(d, '\n\n', d.shape)

输出
[[[ 0  1  2]
  [ 0  3  6]]

 [[ 3  4  5]
  [ 9 12 15]]

 [[ 6  7  8]
  [18 21 24]]] 

 (3, 2, 3)

与例A结果比较,是一致的。
由此我们也可以理解为什么stack()函数要求各数组形状相等,因为concatenate()函数要求各数组除axis指定维度外其余维度元素个数对应相等,而在stack()函数中这条axis指定维度是附加的,并不是参数数组本来的维度。

以上

你可能感兴趣的:(Python数据分析,python,numpy)