numpy中数组的拼接与扩维

numpy中数组的拼接与扩维

一、np.concatenate()函数介绍

在numpy中进行数组拼接,concatenate()函数时最常用的方式之一,这个函数的基本格式是——combined = np.concatenate([array1,array2,…,arrayn],axis)
其中第一个参数以列表的形式“记录”需要进行拼接的数组,第二个参数axis取值为0或者1,表示在数组的哪个“维度”上进行拼接。

二、例子

例1

import numpy as np
a = np.arange(6).reshape((2,3))
b = np.arange(6,12).reshape((2,3))
c = np.arange(12,15).reshape((1,3))
print(a)
print(b)
print(c)
[[0 1 2]
 [3 4 5]]
[[ 6  7  8]
 [ 9 10 11]]
[[12 13 14]]
combined_1 = np.concatenate([a,b,c],axis=0)
print(combined_1)
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]
 [12 13 14]]
combined_2 = np.concatenate([a,b],axis=1)
print(combined_2)
[[ 0  1  2  6  7  8]
 [ 3  4  5  9 10 11]]
combined_3 = np.concatenate([a,b,c],axis=1)
print(combined_3)
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

 in ()
----> 1 combined_3 = np.concatenate([a,b,c],axis=1)
      2 print(combined_3)


ValueError: all the input array dimensions except for the concatenation axis must match exactly

小结:总结一下规律:可以将一个二维数组看成是一个数表或者矩阵,当这样的两个数表或者矩阵进行拼接时,在axis=0的情况下,其实就是将这个数表或者矩阵进行“增行”,也就是列数不变,但是行数增加了。而当axis=1时,就是对这个数表或者矩阵进行“扩列”,也就是行数没有变化,而列数增加了。对应到实际应用中去,前者意味着将数表或矩阵中的样本数量进行增加,但是不改变样本的“字段”(field)数量,后者则表示样本的数量不改变,但是样本的“字段”数量改变,这也就是说,样本所记录的系统信息结构被改变了。

也正因为如此,所以,很显然,当进行“增行”操作时,必须保持拼接的两个数表或者矩阵的“列数”是一致的;而当进行“扩列”时,那么对应地,行数必须是一致的。但是无论如何,首先的条件是,两个数表或者矩阵必须都得是二维的。为了更好的说明这点,我们用下面换一个例子来进行说明。

例2

d = np.array([15,16,17])
print(d)
[15 16 17]
combined_4 = np.concatenate([a,d],axis=0)
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

 in ()
----> 1 combined_4 = np.concatenate([a,d],axis=0)


ValueError: all the input arrays must have same number of dimensions

这就进一步说明,在进行ndarray的拼接时,必须保持数组维度的一致,在这个前提下,再根据需求进行“增行”或者“扩列”

例3(三维情况下,不考虑四维及以上的情况)

a = np.arange(12).reshape((2,2,3))
b = np.arange(12,24).reshape((2,2,3))
c = np.arange(24,30).reshape((2,1,3))
print(a)
print("****************************")
print(b)
print("****************************")
print(c)
[[[ 0  1  2]
  [ 3  4  5]]

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

 [[18 19 20]
  [21 22 23]]]
****************************
[[[24 25 26]]

 [[27 28 29]]]
combine_1 = np.concatenate([a,b],axis=0)
print(combine_1)
[[[ 0  1  2]
  [ 3  4  5]]

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

 [[12 13 14]
  [15 16 17]]

 [[18 19 20]
  [21 22 23]]]
combine_2 = np.concatenate([a,b],axis=1)
print(combine_2)
[[[ 0  1  2]
  [ 3  4  5]
  [12 13 14]
  [15 16 17]]

 [[ 6  7  8]
  [ 9 10 11]
  [18 19 20]
  [21 22 23]]]
combine_3 = np.concatenate([a,c],axis=0)
print(combine_3)
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

 in ()
----> 1 combine_3 = np.concatenate([a,c],axis=0)
      2 print(combine_3)


ValueError: all the input array dimensions except for the concatenation axis must match exactly
combine_4 = np.concatenate([b,c],axis=1)
print(combine_4)
[[[12 13 14]
  [15 16 17]
  [24 25 26]]

 [[18 19 20]
  [21 22 23]
  [27 28 29]]]

小结:三维的情况下,可能的情况如上述,但不作深入的探讨,因为现实生活中,大部分数据是以矩阵和数表的形式出现的,因此,二维情况下的拼接更有意义。三维的情况作为展示,需要时可以临时研究其变化规律,但总体来说,将其最后一维“降维”成普通的数据元素进行对待即可,其实和二维的规律差不多。

三、np.expand_dims()函数介绍

该函数可以改变数组的维度,对数组进行“扩维”操作,其形式为array_expanded = np.expand_dims(array,axis)
同样的,array表示需要进行“扩维”操作的数组,而axis表示在数组的哪个“维度”上进行扩维。

四、例子

a = np.array([1,2,3,4,5])
print(a)
[1 2 3 4 5]
a_2d_0 = np.expand_dims(a,axis=0)
print(a_2d_0)
[[1 2 3 4 5]]
a_2d_1 = np.expand_dims(a,axis=1)
print(a_2d_1)
[[1]
 [2]
 [3]
 [4]
 [5]]
b = np.arange(12).reshape((3,4))
print(b)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
b_2d_0 =np.expand_dims(b,axis=0)
print(b_2d_0)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]]
b_2d_1 =np.expand_dims(b,axis=1)
print(b_2d_1)
[[[ 0  1  2  3]]

 [[ 4  5  6  7]]

 [[ 8  9 10 11]]]

结论:同样的,通过观察可以发现,不论是由一维扩展成二维还是由二维扩展成三维,都有一个规律:当axis=0时,其实就是在原数组的基础上直接再加一个中括号(square bracket)即可,而当axis=1时,便是将原来数组中的“第二维”的向量取出(按:读者须要会意“第二维”的含义,其实就是第二个中括号所包含的那个向量),然后对其“扩维”(所谓的扩维其实就是增加一个中括号)即可。

五、两个函数的使用场景

先假设有某数表A为3x3形式,取其第一列A[:,0],第三列A[:,2],再将二者相除,得B=A[:,0]/A[:,2]。此时,显然,B向量表示了原有数表经过计算后的某个系统信息。那么现在的需求就是将其作为列“增加”到原有的数表中去。请问如何操作?show me the code

解:显然这时需要用concatenate方法将AB进行拼接,然而如上所述,当进行“扩列”拼接时,需要保持两个矩阵维度一致以及行数一致。而B显然是一维的,有三个元素的数组,因此也就需要对B使用expand_dims进行“扩维”。最后进行拼接。具体伪代码如下:

B_2d = np.expand_dims(B,axis=1)

combined = np.concatenate([A,B],axis=1)

六、一点补充

关于轴参数axis,在对数组进行数学运算的时候,也是可以使用的,比如

a = np.arange(12).reshape((2,6))
print(a)
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]]
a.min(axis=1)
array([0, 6])
a.min(axis=0)
array([0, 1, 2, 3, 4, 5])
a.mean(axis=0)
array([3., 4., 5., 6., 7., 8.])
a.mean(axis=1)
array([2.5, 8.5])

结论:在concatenate函数和expand_dims函数中,axis参数为0时,不论是拼接还是扩维,总是对数表按照“横向”进行操作,为1时,则进行“竖向”操作。但当对数组进行数学运算的时候,axis=0则是进行“竖向”操作,axis=1则进行“横向”操作。这二者对该参数的使用是不同的,这点要注意。

你可能感兴趣的:(numpy中数组的拼接与扩维)