美文网首页【完】Numpy学习笔记
【numpy笔记_8】array对象的拼接、分割

【numpy笔记_8】array对象的拼接、分割

作者: fakeProgramer | 来源:发表于2023-02-27 20:16 被阅读0次

    像上篇最后说的,“轴”概念是numpy中很重要的概念。对一个ndarray来说,轴用0,1,2,...,n-1表示。

    轴既代表数组颗粒度的大小,从0轴到n轴颗粒度递增,即数组单位越来越小。
    同时,“轴”又可以理解为对ndarray的shape(1,2,3,...,n)的索引,0轴指向了1。

    回顾完轴的概念,我们开始今天的学习。
    拼接与分割都是调用不同的方法。

    拼接

    拼接数组和序列,浅记一下:

    方法 描述 常用的参数
    np.concatenate() (数组)拼接在指定轴之后 多个数组的元组
    axis: 指定拼接的轴
    np.stack() (数组)拼接在新轴之后 多个数组的元组
    axis: 指定的基准轴,用于调整拼接的颗粒度
    np.hstack() (数组)拼接在行上(水平拼接) /
    np.vstack() (数组)拼接在列上(垂直拼接) /

    np.concatenate()方法:(数组)拼接在指定轴之后

    • 多个数组的元组
    • axis: 指定拼接的轴。
    import numpy as np
    arr1 = np.arange(12).reshape(3,4)
    arr2 = np.ones(12).reshape(3,4)
    concatenate_it_axis0 = np.concatenate((arr1,arr2), axis=0)  # 指定在0轴上拼接,即行延续
    concatenate_it_axis1 = np.concatenate((arr1,arr2), axis=1)  # 指定在1轴上拼接,即列延续
    print('concatenate_it_axis0的拼接效果:\n', concatenate_it_axis0)
    print('concatenate_it_axis1的拼接效果:\n', concatenate_it_axis1)
    # 运行结果:
    concatenate_it_axis0的拼接效果:
    [[ 0.  1.  2.  3.]
     [ 4.  5.  6.  7.]
     [ 8.  9. 10. 11.]
     [ 1.  1.  1.  1.]
     [ 1.  1.  1.  1.]
     [ 1.  1.  1.  1.]]
    concatenate_it_axis1的拼接效果:
    [[ 0.  1.  2.  3.  1.  1.  1.  1.]
     [ 4.  5.  6.  7.  1.  1.  1.  1.]
     [ 8.  9. 10. 11.  1.  1.  1.  1.]]
    

    np.stack()方法:(数组)拼接在新轴之后

    • 多个数组的元组
    • axis: 指定的基准轴,用于调整拼接的颗粒度。

    这个方法抽象一点。我们试着理解一下:
    由于stack()方法是增加新轴,所以对于一个shape(b,a)而言,新数组的shape其实为(c,b,a)
    axis参数的书写标准也在于此,用以指定数据拼接时的颗粒度大小,即对于shape(b,a):

    axis=0:增加新轴,块块拼接(直接以增加新轴的方式对两个数组拼接)
    axis=1:增加新轴,行行拼接
    axis=2:增加新轴,列列拼接

    思考一下,如果是拼接两个数组的shape(c,b,a),axis怎么写呢?
    没错,stack()后的数组,其shape就变成了(d,c,b,a),所以axis的效果就像这样:

    axis=0:增加新轴,大块进行拼接(也相当于两个数组直接拼接)
    axis=1:增加新轴,块块拼接
    axis=2:增加新轴,行行拼接
    axis=3:增加新轴,列列拼接

    是的,其实不难理解。

    结合例子看下:

    import numpy as np
    arr1 = np.arange(12).reshape(3,4)
    arr2 = np.ones(12).reshape(3,4)
    atack_it_axis2 = np.stack((arr1,arr2), axis=2)  # 增加新轴,列列拼接
    atack_it_axis0 = np.stack((arr1,arr2), axis=0)  # 增加新轴,直接拼接
    atack_it_axis1 = np.stack((arr1,arr2), axis=1)  # 增加新轴,行行拼接
    
    print('atack_it_axis2,增加新轴的拼接数组:\n',atack_it_axis2)
    print('atack_it_axis0,增加新轴的拼接数组:\n',atack_it_axis0)
    print('atack_it_axis1,增加新轴的拼接数组:\n',atack_it_axis1)
    # 运行结果:
    atack_it_axis2,增加新轴的拼接数组:
     [[[ 0.  1.]
      [ 1.  1.]
      [ 2.  1.]
      [ 3.  1.]]
    
     [[ 4.  1.]
      [ 5.  1.]
      [ 6.  1.]
      [ 7.  1.]]
    
     [[ 8.  1.]
      [ 9.  1.]
      [10.  1.]
      [11.  1.]]]
    atack_it_axis0,增加新轴的拼接数组:
     [[[ 0.  1.  2.  3.]
      [ 4.  5.  6.  7.]
      [ 8.  9. 10. 11.]]
    
     [[ 1.  1.  1.  1.]
      [ 1.  1.  1.  1.]
      [ 1.  1.  1.  1.]]]
    atack_it_axis1,增加新轴的拼接数组:
     [[[ 0.  1.  2.  3.]
      [ 1.  1.  1.  1.]]
    
     [[ 4.  5.  6.  7.]
      [ 1.  1.  1.  1.]]
    
     [[ 8.  9. 10. 11.]
      [ 1.  1.  1.  1.]]]
    
    无论是np.concatenate()还是np.stack(),拼接一个数组,要求两个拼接的对象的维度要相同。

    这很好理解,因为不同维度的错误拼接就像这张图一样:


    维度错误的数组拼接.png
    np.hstack()水平拼接(延续列)和np.vstack()垂直拼接(延续行)就没什么好讲的,直接传入数组就行。np.concatenate()方法同样能完成这些操作。

    分割

    方法 描述 常用的参数
    np.split() 沿指定轴切分 ary: 要分割的数组;
    axis: 指定分割的轴
    np.hsplit() (数组)按轴水平分割 ary: 要分割的数组;
    axis: 指定分割的轴
    np.vsplit() (数组)按轴垂直分割 ary: 要分割的数组;
    axis: 指定分割的轴

    用一个例子看看np.split()的操作,其他的用法类似就不多讲了:

    import numpy as np
    arr1 = np.arange(16).reshape(4,4)
    res1, res2 = np.split(arr1, 2)  # 平均2等分,按行(axis不写默认=0)
    print('arr1:\n', arr1)
    print('arr1切开前半段:\n', res1)
    print('arr1切开后半段:\n', res2)
    # 运行结果:
    arr1:
     [[ 0  1  2  3]
     [ 4  5  6  7]
     [ 8  9 10 11]
     [12 13 14 15]]
    arr1切开前半段:
     [[0 1 2 3]
     [4 5 6 7]]
    arr1切开后半段:
     [[ 8  9 10 11]
     [12 13 14 15]]
    
    arr1 = np.arange(16).reshape(4,4)
    res1, res2 = np.split(arr1, 2, axis=1)  # 平均2等分,按列
    print('arr1:\n', arr1)
    print('arr1切开前半段:\n', res1)
    print('arr1切开后半段:\n', res2)
    # 运行结果:
    arr1:
     [[ 0  1  2  3]
     [ 4  5  6  7]
     [ 8  9 10 11]
     [12 13 14 15]]
    arr1切开前半段:
     [[ 0  1]
     [ 4  5]
     [ 8  9]
     [12 13]]
    arr1切开后半段:
     [[ 2  3]
     [ 6  7]
     [10 11]
     [14 15]]
    
    arr1 = np.arange(16).reshape(4,4)
    res1, res2 = np.split(arr1, 3)  # 平均3等分。分不成三块,报错
    print('arr1:\n', arr1)
    print('arr1切开前半段:\n', res1)
    print('arr1切开后半段:\n', res2)
    # 运行结果:
    报错
    
    arr1 = np.arange(16).reshape(4,4)
    res1, res2 = np.split(arr1, [1])  # 切第一行与后面几行
    print('arr1:\n', arr1)
    print('arr1切开前半段:\n', res1)
    print('arr1切开后半段:\n', res2)
    # 运行结果:
    arr1:
     [[ 0  1  2  3]
     [ 4  5  6  7]
     [ 8  9 10 11]
     [12 13 14 15]]
    arr1切开前半段:
     [[0 1 2 3]]
    arr1切开后半段:
     [[ 4  5  6  7]
     [ 8  9 10 11]
     [12 13 14 15]]
    
    arr2 = np.arange(12)
    res1, res2 = np.split(arr2, indices_or_sections=[3])  # 按元素切。指定的元素在后面数组的第一位
    print('arr1:\n', arr2)
    print('arr1切开前半段:\n', res1)
    print('arr1切开后半段:\n', res2)
    # 运行结果:
    arr1:
     [ 0  1  2  3  4  5  6  7  8  9 10 11]
    arr1切开前半段:
     [0 1 2]
    arr1切开后半段:
     [ 3  4  5  6  7  8  9 10 11]
    

    相关文章

      网友评论

        本文标题:【numpy笔记_8】array对象的拼接、分割

        本文链接:https://www.haomeiwen.com/subject/ckmhldtx.html