【Numpy】连接数组

前言

本篇总结、介绍Numpy数组(ndarray)的基本操作之一——连接数组 [1]

1. concatenate

numpy.concatenate((a1, a2, …), axis=0, out=None, dtype=None, casting=“same_kind”):沿现有的轴连接一系列数组

  • a1, a2, …:类数组(array_like)的序列。这些数组在除了axis参数对应的维度上,必须具有相同的形状
  • axis:整数型,可选参数。连接数组所沿的轴。
    • 如果axis = None:数组会先被展平,再进行连接
  • out:ndarray对象,可选参数。放置结果的地方( destination)
  • dtype:数据类型,可选参数。如果指定,那么必须与 destination数组的数据类型一致。另外,dtype参数不能和out参数一起指定(Numpy 1.20.0版本开始引入的输入参数)
  • casting:{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’},可选参数。控制可能发生的数据类型转换,默认“same_kind”(Numpy 1.20.0版本开始引入的输入参数)
>>> arr1 = np.array([[1,2],[3,4]])
>>> arr1.shape
(2, 2)

>>> arr2 = np.array([[5,6]])
>>> arr2.shape
(1, 2)

>>> np.concatenate((arr1,arr2),axis=0)
array([[1, 2],
       [3, 4],
       [5, 6]])

>>> np.concatenate((arr1,arr2.T),axis=1)
array([[1, 2, 5],
       [3, 4, 6]])

>>> np.concatenate((arr1,arr2),axis=None)
array([1, 2, 3, 4, 5, 6])

>>> arr3 = np.zeros((3,2))
>>> arr3
array([[0., 0.],
       [0., 0.],
       [0., 0.]])
>>> np.concatenate((arr1,arr2),axis=0,out=arr3)
array([[1., 2.],
       [3., 4.],
       [5., 6.]])
>>> np.concatenate(arr1,arr2,axis=0)
TypeError: concatenate() got multiple values for argument 'axis'

注释:
数组不能一个个单独传入,必须以列表或元组等形式整体传入,下同

>>> arr1 = np.array([[1,2],[3,4]])
>>> arr2 = np.array([[5,6]])

>>> np.concatenate(arr1,arr2)
Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
    np.concatenate(arr1,arr2)
  File "<__array_function__ internals>", line 5, in concatenate
TypeError: only integer scalar arrays can be converted to a scalar index

2. stack

numpy.stack(arrays, axis=0, out=None):沿一个新的轴连接一系列数组

  • arrays:类数组的序列。每个数组都必须具有相同的形状
  • axis:整数型,可选参数。数组沿其堆叠的轴
    • axis = 0:第一维
    • axis = -1:最后一维
  • out:
>>> arrays = [np.random.randint(0,10,(2,3)) for _ in range(4)]
>>> arrays
[array([[4, 4, 1],
       [9, 6, 1]]), array([[3, 3, 6],
       [7, 4, 3]]), array([[2, 2, 7],
       [3, 9, 6]]), array([[5, 4, 3],
       [2, 2, 6]])]

>>> np.stack(arrays,axis=0)
array([[[4, 4, 1],
        [9, 6, 1]],

       [[3, 3, 6],
        [7, 4, 3]],

       [[2, 2, 7],
        [3, 9, 6]],

       [[5, 4, 3],
        [2, 2, 6]]])
>>> np.stack(arrays,axis=0).shape
(4, 2, 3)

>>> np.stack(arrays,axis=-1)
array([[[4, 3, 2, 5],
        [4, 3, 2, 4],
        [1, 6, 7, 3]],

       [[9, 7, 3, 2],
        [6, 4, 9, 2],
        [1, 3, 6, 6]]])
>>> np.stack(arrays,axis=-1).shape
(2, 3, 4)

>>> np.stack(arrays,axis=1)
array([[[4, 4, 1],
        [3, 3, 6],
        [2, 2, 7],
        [5, 4, 3]],

       [[9, 6, 1],
        [7, 4, 3],
        [3, 9, 6],
        [2, 2, 6]]])
>>> np.stack(arrays,axis=1).shape
(2, 4, 3)

3. block

numpy.block(arrays):从嵌套的块列表中组装一个Numpy数组(ndarray)

  • arrays:类数组或标量组成的嵌套列表(非元组
>>> np.block([1,2])
array([1, 2])

>>> np.block((1,2))
TypeError: arrays is a tuple. Only lists can be used to arrange blocks, and np.block does not allow implicit conversion from tuple to ndarray.

>>> np.block([np.array([1,2]),np.array([3,4])])
array([1, 2, 3, 4])

>>> np.block((np.array([1,2]),np.array([3,4])))
TypeError: arrays is a tuple. Only lists can be used to arrange blocks, and np.block does not allow implicit conversion from tuple to ndarray.
>>> np.block([np.array([1,2]),np.array([3,4])])

列表最里层的块沿着最后一个维度(-1)连接(numpy.concatenate),然后是次里层的块沿着倒数第二个维度(-2)连接,以此类推,直到最外层:

  • 如果传入单个数组,那么返回元素没有任何变化的副本
>>> np.block(np.array([1,2]))
array([1, 2])

>>> np.block([np.array([1,2])])
array([1, 2])

>>> arr1 = np.array([1,2])
>>> arr2 = np.block(arr1)
>>> arr1[0] = -1
>>> arr1
array([-1,  2])
>>> arr2
array([1, 2])
  • 如果传入标量组成的嵌套列表,那么numpy.block等同于numpy.array
>>> np.block([1,2])
array([1, 2])

>>> np.block([[1, 2], [3, 4]])
array([[1, 2],
       [3, 4]])
  • 如果嵌套列表的深度为1,numpy.block可以被用作numpy.hstack
>>> arr1 = np.array([1, 2, 3])
>>> arr2 = np.array([2, 3, 4])

>>> np.block([arr1,arr2])
array([1, 2, 3, 2, 3, 4])

>>> np.hstack((arr1,arr2))
array([1, 2, 3, 2, 3, 4])
  • 如果嵌套列表的深度为2,numpy.block可以被用作numpy.vstack
>>> arr1 = np.array([1, 2, 3])
>>> arr2 = np.array([2, 3, 4])

>>> np.block([[arr1],[arr2]])
array([[1, 2, 3],
       [2, 3, 4]])

>>> np.vstack((arr1,arr2))
array([[1, 2, 3],
       [2, 3, 4]])
  • 如果嵌套列表中元素的深度不匹配,例如[[a,b],c],否则会引起错误
>>> np.block([[1,2],3])
ValueError: List depths are mismatched. First element was at depth 2, but there is an element at depth 1 (arrays[1])
  • 如果嵌套列表中存在空列表,例如 [[a, b], []],也会引起错误
>>> np.block([])
ValueError: List at arrays cannot be empty

>>> np.block([[1,2],[]])
ValueError: List at arrays[1] cannot be empty
  • 如果嵌套列表只有两层深时,那么可以从中构建块矩阵,这是numpy.block函数最常见的用法
>>> A = np.eye(2) * 2
>>> B = np.eye(3) * 3
>>> np.block([
    [A,               np.zeros((2, 3))],
    [np.ones((3, 2)), B               ]
])
array([[2., 0., 0., 0., 0.],
       [0., 2., 0., 0., 0.],
       [1., 1., 3., 0., 0.],
       [1., 1., 0., 3., 0.],
       [1., 1., 0., 0., 3.]])

4. hstack

numpy.hstack(tup):沿水平方向堆叠数组(列优先,column wise)

  • tup:类数组序列。这些数组必须在除了第二个轴以外的轴/维度上具有相同的形状
    • 对于一维数组,其可以是任意长度,即形状可以不同
# 一维数组
>>> arr1 = np.array([1,2,3])
>>> arr2 = np.array([4,5])

>>> np.hstack((arr1,arr2))
array([1, 2, 3, 4, 5])

# 二维数组
>>> arr3 = np.arange(6).reshape(3,2)
>>> arr3
array([[0, 1],
       [2, 3],
       [4, 5]])
>>> arr4 = np.arange(6,9).reshape(-1,1)
>>> arr4
array([[6],
       [7],
       [8]])
>>> arr5 = arr4.T
>>> arr5
array([[6, 7, 8]])

>>> np.hstack((arr3,arr4))
array([[0, 1, 6],
       [2, 3, 7],
       [4, 5, 8]])

## 数组在除第二个轴以外的轴上的形状必须匹配
>>> np.hstack((arr3,arr5))
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 0, the array at index 0 has size 3 and the array at index 1 has size 1

注释:
numpy.hstack对于高维数组(维度大于3)而言意义不大,因为numpy.hstack等同于numpy.concatenate(axis=1) (一维数组的情况下,numpy.hstack等同于numpy.concatenate(axis=0) ),但numpy.hstack远没有numpy.concatenate灵活。


5. vstack

numpy.vstack(tup):沿垂直方向堆叠数组(行优先,row wise)

  • tup:类数组序列。这些数组必须在除了第一个轴以外的轴/维度上具有相同的形状
    • 对于一维数组,其长度必须相等,即形状相同
# 一维数组
>>> arr1 = np.array([1,2,3])
>>> arr2 = np.array([4,5,6])
>>> arr3 = np.array([7,8])

>>> np.vstack((arr1,arr2))
array([[1, 2, 3],
       [4, 5, 6]])
## 对于一维数组,其长度必须相等  
>>> np.vstack((arr1,arr3))
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 3 and the array at index 1 has size 2

# 二维数组
>>> arr4 = np.arange(6).reshape(3,2)
>>> arr4
array([[0, 1],
       [2, 3],
       [4, 5]])
>>> arr5 = np.arange(6,12).reshape(-1,2)
>>> arr5
array([[ 6,  7],
       [ 8,  9],
       [10, 11]])
>>> arr6 = arr5.T
>>> arr6
array([[ 6,  8, 10],
       [ 7,  9, 11]])

>>> np.vstack((arr4,arr5))
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11]])
## 数组在除第一个轴以外的轴上的形状必须匹配
>>> np.vstack((arr4,arr6))
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 2 and the array at index 1 has size 3

注释:
numpy.vstack对于高维数组(维度大于3)而言意义不大,因为numpy.vstack等同于numpy.concatenate(axis=0)(对于一维数组,需要先将形状为(N,)的一维数组变成形状为(1, N)的二维数组) ,但numpy.vstack远没有numpy.concatenate灵活。

>>> arr1 = np.array([1,2,3])
>>> arr2 = np.array([4,5,6])

# numpy.vstack
>>> np.vstack((arr1,arr2))
array([[1, 2, 3],
       [4, 5, 6]])

# 如果直接使用numpy.concatenate
>>> np.concatenate((arr1,arr2))
array([1, 2, 3, 4, 5, 6])

# 先使用reshape(1,-1)将一维数组变为二维数组,再使用numpy.concatenate
>>> np.concatenate((arr1.reshape(1,-1),arr2.reshape(1,-1)))
array([[1, 2, 3],
       [4, 5, 6]])

6. dstack

numpy.dstack(tup):沿第三轴堆叠数组(深度优先,depth wise)

  • tup:类数组序列。这些数组必须在除了第三个轴以外的轴/维度上具有相同的形状
    • 对于一维数组,其长度必须相等,即形状相同
    • 对于二维数组,其形状必须相同

numpy.dstack的使用方法和numpy.hstack以及numpy.vstack类似,在此不再赘述。


注释:
numpy.dstack等同于沿第三轴进行concatenate,即numpy.concatenate(axis=2):

  • 对于一维数组:需先将形状为(N,)的一维数组重塑为形状为(1,N,1)的三维数组
  • 对于二维数组:需先将形状为(M,N)的二维数组重塑为形状为(M,N,1)的三维数组
>>> arr1 = np.array([1,2,3])
>>> arr2 = np.array([4,5,6])
>>> arr3 = np.array([[1,2,3]])
>>> arr4 = np.array([[4,5,6]])

>>> np.dstack((arr1,arr2))
array([[[1, 4],
        [2, 5],
        [3, 6]]])
>>> np.concatenate((arr1.reshape(1,-1,1),arr2.reshape(1,-1,1)),axis=2)
array([[[1, 4],
        [2, 5],
        [3, 6]]])

>>> np.dstack((arr3,arr4))
array([[[1, 4],
        [2, 5],
        [3, 6]]])
>>> np.concatenate((arr3.reshape(arr3.shape[0],arr3.shape[1],1),arr4.reshape(arr4.shape[0],arr4.shape[1],1)),axis=2)
array([[[1, 4],
        [2, 5],
        [3, 6]]])

7. column_stack

numpy.column_stack(tup):将一维数组作为列堆叠到二维数组中

  • tup:一维或二维数组序列
    • 一维数组:等同于先将形状为(N,)的一维数组重塑为形状为(N,1)的二维数组之后的hstack函数,因此一维数组的长度得相同
    • 二维数组:等同于hstack函数
>>> arr1 = np.array([1,2,3])
>>> arr2 = np.array([4,5,6])

>>> np.column_stack((arr1,arr2))
array([[1, 4],
       [2, 5],
       [3, 6]])

>>> np.hstack((arr1.reshape(-1,1),arr2.reshape(-1,1)))
array([[1, 4],
       [2, 5],
       [3, 6]])

>>> np.hstack((arr1,arr2))
array([1, 2, 3, 4, 5, 6])

8. row_stack

numpy.row_stack(tup):按垂直顺序堆叠数组(行优先),等同于vstack

Reference

[1]: https://numpy.org/doc/stable/reference/routines.array-manipulation.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值