数组拼接和分裂
1 数组的拼接
拼接或连接Numpy中的两个数组主要由np.concatenate
、np.vstack
、np.hstack
实现。
np.concatenate
将数组元祖或数组列表作为第一个参数,如下所示
In[1]: x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
np.concatenate([x, y])
Out[1]: array([1, 2, 3, 3, 2, 1])
你也可以一次性拼接两个以上的数组
In[2]: z = [99, 99, 99]
print(np.concatenate([x, y, z]))
Out[2]: [ 1 2 3 3 2 1 99 99 99]
np.concatenate
也可以用于二维数组的拼接
In[3]: grid = np.array([[1, 2, 3],
[4, 5, 6]])
In[4]: # 沿着第一个轴拼接(默认axis=0)
np.concatenate([grid, grid])
Out[4]: array([[1, 2, 3],
[4, 5, 6],
[1, 2, 3],
[4, 5, 6]])
In[5]: # 沿着第二个轴拼接(axis=1)
np.concatenate([grid, grid],axis=1)
Out[5]: array([[1, 2, 3, 1, 2, 3],
[4, 5, 6, 4, 5, 6]])
沿着固定维度处理数据时,使用np.vstack(垂直栈)、np.hstack(水平栈)函数会更简洁
In[6]: x = np.array([1, 2, 3])
grid = np.array([[9, 8, 7],
[6, 5, 4]])
# 垂直栈数组
np.vstack([x, grid])
Out[6]: array([[1, 2, 3],
[9, 8, 7],
[6, 5, 4]])
In[7]: np.vstack([x, x])
Out[7]: array([[1, 2, 3],
[1, 2, 3]])
In[8]: # 水平栈数组
y = np.array([[99],
[99]])
np.hstack([grid, y])
Out[8]: array([[ 9, 8, 7, 99],
[ 6, 5, 4, 99]])
我想到的一个实际应用,比如我们想将一个5*5大小的三通道图片,和它的梯度图(单通道)进行拼接,成为一个5*5大小的4通道图
>>> A = np.random.random(75).reshape(3,5,5)
>>> B = np.random.random(25).reshape(1,5,5)
>>> C = np.concatenate((A,B),axis=0)
>>> C.shape
(4, 5, 5)
2 数组的分裂
与拼接相反的过程是分裂。分裂可以通过np.split
、np.hsplit
、np.vsplit
函数来实现。
可以向以上函数传递一个索引列表作为参数,索引列表记录的是分裂点的位置:
In[9]: x = [1, 2, 3, 99, 99, 3, 2, 1]
x1, x2, x3 = np.split(x, [3, 5])
print(x1, x2, x3)
Out[9]: [1 2 3] [99 99] [3 2 1]
In[10]: A = np.arange(12).reshape((3, 4))
np.split(A,[2],axis=1)
Out[10]:[array([[0, 1],
[4, 5],
[8, 9]]),
array([[ 2, 3],
[ 6, 7],
[10, 11]])]
In[11]: np.split(A,2,axis=1) #这里的2是均分成两个 对于A数组,如果写3就会报错
Out[11]:[array([[0, 1],
[4, 5],
[8, 9]]),
array([[ 2, 3],
[ 6, 7],
[10, 11]])]
In[12]: np.split(A,[2],axis=0)
Out[12]:[array([[0, 1, 2, 3],
[4, 5, 6, 7]]),
array([[ 8, 9, 10, 11]])]
值得注意的是,N个分裂点会得到N+1个子数组。相关的np.hsplit
、np.vsplit
也类似。
对于axis的理解,简单的来记就是axis=0代表往跨行(down),而axis=1代表跨列(across)。因此对于split中的axis可以参照下图理解,这样应该会比较简洁明了。
In[13]: grid = np.arange(16).reshape((4, 4))
grid
Out[13]:array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In[14]: upper, lower = np.vsplit(grid, [2])
print(upper)
print(lower)
[[0 1 2 3]
[4 5 6 7]]
[[ 8 9 10 11]
[12 13 14 15]]
In[15]: left, right = np.hsplit(grid, [2])
print(left)
print(right)
[[ 0 1]
[ 4 5]
[ 8 9]
[12 13]]
[[ 2 3]
[ 6 7]
[10 11]
[14 15]]