5 NumPy数组的合并

Numpy里提供了很多的函数可以实现数组的合并。

5.1 数组的合并

实现Numpy的数组的合并函数有水平合并和垂直合并函数,水平合并的有hstack、concatenate等。

1). hstack水平合并

hstack函数可以将多个维度相同的数组合并成一个更大的数组。

from numpy import *
a = arange(9).reshape([3, 3])
print a
b = a * 2
print b
c = hstack((a, b, a))
print c

程序的执行结果如下所示:

[[0 1 2] # a
 [3 4 5]
 [6 7 8]]
[[ 0  2  4] # b = a * 2
 [ 6  8 10]
 [12 14 16]]
 # c 
[[ 0  1  2  0  2  4  0  1  2]
 [ 3  4  5  6  8 10  3  4  5]
 [ 6  7  8 12 14 16  6  7  8]]

c = hstack((a, b, a))的执行结果可以看出函数hstack的作用是将a、b、a沿水平方向缝合成一个更大的数组c了,c的前3列和最后3列都来自于a,而中间的3列来自于b数组。

2).concatenate水平合并

concatenate函数和hstack函数的作用一样也是水平(axis = 1)拼接数组成一个更大的数组。

from numpy import *
a = arange(9).reshape([3, 3])
print a
b = arange(12).reshape([3, 4])
# b和a的行数不同,不能水平合并。
#b = arange(16).reshape([4, 4])
print b
c = concatenate((a, b, a), axis = 1)
print c

程序的执行结果如下所示:

[[0 1 2]
 [3 4 5]
 [6 7 8]]
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[[ 0  1  2  0  1  2  3  0  1  2]
 [ 3  4  5  4  5  6  7  3  4  5]
 [ 6  7  8  8  9 10 11  6  7  8]]

hstack函数的示例程序和concatenate函数的示例程序的区别有两个,一个是函数不同这个显然,另一个是b数组的维度值不同,在hstack函数的示例程序里a、b、a的维度值是完全相同的均是(3, 3)的数组,而concatenate函数的b是(3, 4)的数组,从程序的运行结果可以看出也能合并数组,即水平合并数组时要求所有的数组的行数必须相同,同理后续的垂直合并数组的时候,要求数组列数相同

3). vstack垂直合并

vstack的用法和hstack差不多,实现的是将列数相同的数组垂直方向缝合合并成一个数组。

from numpy import *
a = arange(9).reshape([3, 3])
print a
b = a * 2
print b
c = vstack((a, b, a))
print c

4).concatenate垂直合并

在使用本函数将列数相同的数组垂直(axis = 0)合并成一个新数组。

from numpy import *
a = arange(9).reshape([3, 3])
print a
b = a * 2
print b
c = concatenate((a, b, a), axis = 0)
print c

程序的执行结果如下:

[[0 1 2]
 [3 4 5]
 [6 7 8]]
[[ 0  2  4]
 [ 6  8 10]
 [12 14 16]]
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 0  2  4]
 [ 6  8 10]
 [12 14 16]
 [ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]]

5).dstack深度合并

dstack可以将形状相同的一、二维数组沿第三轴合并成一个三维数组。

from numpy import *
a = arange(9).reshape([3, 3])
print a
b = a * 2
print b
c = dstack((a, b, a))
print c

程序的执行结果如下所示:

[[0 1 2] # a
 [3 4 5]
 [6 7 8]]
[[ 0  2  4] # b
 [ 6  8 10]
 [12 14 16]]
[[[ 0  0  0] # c
  [ 1  2  1]
  [ 2  4  2]]

 [[ 3  6  3]
  [ 4  8  4]
  [ 5 10  5]]

 [[ 6 12  6]
  [ 7 14  7]
  [ 8 16  8]]]

6).column_stack列合并

函数是针对一维数组合并设计的函数,可以将一维数组合并成二维数组,要求数组的列数相同,取要合并的每个数组同一位置上的数据组成一个数组作为二维数组这个位置上的数据。

from numpy import *
a = arange(9)
print a
b = a * 2
print b
c = column_stack((a, b, a))
print c

程序的执行结果:

[0 1 2 3 4 5 6 7 8]# a 
[ 0  2  4  6  8 10 12 14 16]# b
[[ 0  0  0]# c
 [ 1  2  1]
 [ 2  4  2]
 [ 3  6  3]
 [ 4  8  4]
 [ 5 10  5]
 [ 6 12  6]
 [ 7 14  7]
 [ 8 16  8]]

尽管函数是适用于一维数组,其实更高维的数组也可以使用此函数,即n维数组是由若干个n - 1维组成的一维数组,区别:一维数组的各个元素是数值,而n维数组视为一维数组其各个元素值是n - 1维的数组而已。

from numpy import *
a = arange(9).reshape([3, 3])
print a
b = a * 2
print b
c = column_stack((a, b, a))
print c

程序里的a是二维数组。程序的执行结果如下:

[[0 1 2] # a
 [3 4 5]
 [6 7 8]]
[[ 0  2  4] # b
 [ 6  8 10]
 [12 14 16]] 
 # c
[[ 0  1  2  0  2  4  0  1  2]
 [ 3  4  5  6  8 10  3  4  5]
 [ 6  7  8 12 14 16  6  7  8]]

以c的第一行结果为例说明一下, c[0]= [ 0 1 2 0 2 4 0 1 2]结果是怎么得到的呢?c[0]的前3个和后三个是a[0],中间3个是b[0],a由a[0]、a[1]、a[2]三个数组组成二维数组,忽略a[0]等是数组的概念,那a也可以看成是一维数组。

6).row_stack行合并

和column_stack相对的行合并,Numpy里的row_stack函数可实现行合并,严格意义上来说也是针对于一维数组的。

from numpy import *
a = arange(9)#.reshape([3, 3])
print a
b = a * 2
print b
c = row_stack((a, b, a))
print c

执行结果:

[0 1 2 3 4 5 6 7 8] # a
[ 0  2  4  6  8 10 12 14 16] # b
# c
[[ 0  1  2  3  4  5  6  7  8] 
 [ 0  2  4  6  8 10 12 14 16]
 [ 0  1  2  3  4  5  6  7  8]]

如果是二维数组用了row_stack结果类似于vstack函数。

from numpy import *
a = arange(12).reshape([3, 4])
print a
b = a * 2
print b
c = row_stack((a, b, a))
print c

程序执行结果:

[[ 0  1  2  3] # a
 [ 4  5  6  7]
 [ 8  9 10 11]]
[[ 0  2  4  6] # b
 [ 8 10 12 14]
 [16 18 20 22]]
# c
[[ 0  1  2  3] 
 [ 4  5  6  7]
 [ 8  9 10 11]
 [ 0  2  4  6]
 [ 8 10 12 14]
 [16 18 20 22]
 [ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

5.2 数组的拆分函数

上节讲的是数组的合并,本节是将数组拆分。

1). hsplit水平拆分

hsplit函数的形参有两个,第一个是要拆分的数组,第二个是水平方向拆分出的数组个数。

from numpy import *
a = arange(24).reshape([4, 6])
print a
b = hsplit(a, 3)
for x in b:
    print "*" * 20
    print x

程序执行结果:

[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
********************
[[ 0  1] # a的0、1列
 [ 6  7]
 [12 13]
 [18 19]]
********************
[[ 2  3]# a的2、3列
 [ 8  9]
 [14 15]
 [20 21]]
********************
[[ 4  5]# a的4、5列
 [10 11]
 [16 17]
 [22 23]]

a数组是(4, 6)即4行6列的数组,hsplit的第二个参数是3,那么a数组被拆分出0、1列数组,2、3列数组,4、5列数组这三个数组,行数相同。

2). vsplit垂直拆分

vsplit函数是沿垂直方向去拆分数组。

from numpy import *
a = arange(24).reshape([4, 6])
print a
b = vsplit(a, 2)
for x in b:
    print "*" * 20
    print x

程序的执行结果:

[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
********************
[[ 0  1  2  3  4  5]# a的0、1行
 [ 6  7  8  9 10 11]]
********************
[[12 13 14 15 16 17]# a的2、3行
 [18 19 20 21 22 23]]

3). dsplit深度拆分

和dstack相对,dsplit沿第3轴进行拆分数组。

from numpy import *
a = arange(24).reshape([2, 3, 4])
print a
b = dsplit(a, 2)
for x in b:
    print "*" * 20
    print x

程序执行结果如下:

[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
********************
[[[ 0  1]
  [ 4  5]
  [ 8  9]]

 [[12 13]
  [16 17]
  [20 21]]]
********************
[[[ 2  3]
  [ 6  7]
  [10 11]]

 [[14 15]
  [18 19]
  [22 23]]]

4). split拆分

NumPy的split函数可以实现hsplit、vsplit和dsplit,用法只需增加一个参数axis指定轴,split实现hsplit同样功能时axis = 1。

from numpy import *
a = arange(12).reshape([3, 4])
print a
b = hsplit(a, 2)
for x in b:
    print "*" * 20
    print x

b = split(a, 2, axis = 1)
for x in b:
    print "-" * 20
    print x

程序的执行结果:

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
 # hsplit
********************
[[0 1]
 [4 5]
 [8 9]]
********************
[[ 2  3]
 [ 6  7]
 [10 11]]
 # split
--------------------
[[0 1]
 [4 5]
 [8 9]]
--------------------
[[ 2  3]
 [ 6  7]
 [10 11]]