numpy——合并、拆分

合并

方法 含义
append 将值附加到数组的末尾。
concatenate、ma.concatenate 沿现有轴连接一系列数组。保存输入的mask。
stack 沿新轴堆叠一系列数组。
block 从块组合数组。
hstack 沿水平折叠(沿第二维)
vstack 垂直顺序排列阵列(沿第一维)
dstack 按深度顺序排列数组(沿第三维)
In [1]: import numpy as np

append

np.append(arr,values,axis=None)
  append是将值添加到数组arr副本的末尾,如果指定arr,其中values是和arr相同形状的。如果未指定axis则会默认展平为一维数组。值得注意的是append不会就地发生,而是分配并填充了一个新数组。 因此,在速度上并不是很快。
  默认情况下:

In [2]: a = np.arange(12).reshape(2,3,2)
In [3]: b = np.arange(3)
In [4]: np.append(a,b)
Out[4]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
               11,  0,  1,  2])

  有轴axis的情况下:
  我们可以看到如果制定了轴,上面的ab合并时会报错。这是因为除了指定的轴外,b上的其它轴必须一致才可以。

In [7]: np.append(a,b,axis = 1)
ValueError: all the input arrays must have same number of dimensions

# a的shape是(2,3,2)、所以如果在axis = 1上合并,
# 则b的shape必须是(2,x,2)的样式,x为正整数即可。
In [8]: b = np.arange(4).reshape(2,1,2)
In [9]: np.append(a,b,axis = 1)
Out[9]:
array([[[ 0,  1],
        [ 2,  3],
        [ 4,  5],
        [ 0,  1]],

       [[ 6,  7],
        [ 8,  9],
        [10, 11],
        [ 2,  3]]])
        
# 例如下面定义a(1,2),则如果想在axis = 0插入,
# 则b邀为(x,2)的数组才可以
In [13]: a = np.arange(2).reshape(1,2)
In [14]: b = np.arange(4).reshape(2,2)
In [15]: np.append(a,b,axis = 0)
Out[15]:
array([[0, 1],
       [0, 1],
       [2, 3]])


concatenate

concatenate((a1, a2, ...), axis=0, out=None)
  其中,a1a2等要级联的数组必须是有相同形状的,默认是假设这些数组是三维的,所以如果在轴axis=0上进行级联,那么a1a2等数组的形状必须是(x, _, _)。其中只能x位置可以为不相同的正整数外,其他位置必须一致。

# 默认的是axis = 0
In [13]: a = np.arange(2).reshape(1,2)
In [14]: b = np.arange(4).reshape(2,2)
In [18]: np.concatenate((a,b))
Out[18]:
array([[0, 1],
       [0, 1],
       [2, 3]])

# 如果想在axis = 1上级联,则是不可以的因为除了
# axis = 1外,形状并不相同。
In [19]: np.concatenate((a,b),axis = 1)
ValueError: all the input array dimensions except for 
the concatenation axis must match exactly

# 因此我们将a转置一下就好了。
In [20]: np.concatenate((a.T,b), axis = 1)
Out[20]:
array([[0, 0, 1],
       [1, 2, 3]])

  当axisNone时,合并所有数组元素。

In [21]: np.concatenate((a.T,b),axis = None)
Out[21]: array([0, 1, 0, 1, 2, 3])

  值得注意的是,如果你传入的是MaskedArrays数组,那么使用np.concatenate是不会保存mask的。你需要使用np.ma.concatenate

In [23]: mask_a
Out[23]:
masked_array(
	   data=[0, 1, 2, 3, --],
       mask=[False, False, False, False, True],
       fill_value=2)

In [24]: mask_b
Out[24]:
masked_array(
	   data=[--, 6, 7, 8, 9],
       mask=[True, False, False, False, False],
       fill_value=5)

# 使用np.concatenate无法保存mask
In [25]: np.concatenate((mask_a,mask_b))
Out[25]:
masked_array(
	   data=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
       mask=False,
       fill_value=999999)
# 使用np.ma.concatenate可以保存mask 但依旧保存不了填充值
In [26]: np.ma.concatenate((mask_a,mask_b))
Out[26]:
masked_array(
	   data=[0, 1, 2, 3, --, --, 6, 7, 8, 9],
       mask=[False, False, False, False, True, True, False, False, False, False],
       fill_value=999999)


stack

np.stack(arrays, axis=0, out=None)
  沿新轴连接一系列数组。这里的每个数组必须要有相同的形状(沿轴)。axis指定了新轴的位置。例如,ab的形状都是(3,)。那么ab堆叠后的结果就只能为沿axis=0得到形状(2,3)或者沿axis=1得到形状(3,2)这两种情况。

In [8]: a = np.arange(3)
In [9]: b = np.arange(3,6)

In [11]: np.stack((a,b),axis = 0)
Out[11]:
array([[0, 1, 2],
       [3, 4, 5]])

In [12]: np.stack((a,b),axis = 1)
Out[12]:
array([[0, 3],
       [1, 4],
       [2, 5]])

  再举一个例子,如果ab是一个形状为(4,3)的数组,那么堆叠起来就有axis=0axis=1axis=2分别对应形状(2,4,3),(4,2,3),(4,3,2)这三种。

In [13]: a = np.arange(12).reshape(4,3)
In [14]: b = np.arange(1,13).reshape(4,3)

In [15]: np.stack([a,b],axis = 0).shape
Out[15]: (2, 4, 3)

In [16]: np.stack([a,b],axis = 1).shape
Out[16]: (4, 2, 3)

In [17]: np.stack([a,b],axis = 2).shape
Out[17]: (4, 3, 2)


block

np.block(arrays)
  函数block就是将数组按块排版。就像下图所示的这样,对于矩阵 [ M ] \begin{bmatrix}M\end{bmatrix} ,我们可以通过四小块构成: [ A B C D ] \begin{bmatrix} A&B\\ C&D \end{bmatrix}
在这里插入图片描述

In [4]: a = np.arange(4).reshape(2,2)
In [5]: b = np.arange(6).reshape(2,3)
In [6]: c = np.arange(2).reshape(2,1)S
In [7]: d = np.arange(8).reshape(2,4)

In [8]: np.block([[a,b],[c,d]])
Out[8]:
array([[0, 1, 0, 1, 2],
       [2, 3, 3, 4, 5],
       [0, 0, 1, 2, 3],
       [1, 4, 5, 6, 7]])


hstack、vstack、dstack

hstack

np.hstack(tup)
  hstack方法等价于concatenate方法沿着axis=1级联(1-D数组沿axis=0)。

扫描二维码关注公众号,回复: 8486702 查看本文章
  • 1-D
      通俗理解,hstack的意思是horizontal stack即水平堆叠。假设对于两个形状分别为(3,)和(2,)的1-D数组,因此我们只需要在水平轴上拼接即可。得到一个形状为(5,)的数组。


    1-D
In [3]: a = np.arange(3)
In [4]: b = np.arange(2)

In [5]: np.hstack((a,b))
Out[5]: array([0, 1, 2, 0, 1])

  • 2-D及以上
      现在,让我们在1-D的基础上再加一维,假设对于两个形状分别为(2,3)和(4,5)的2-D数组进行水平堆叠是没有办法堆叠出一个规则数组的。我们令ab分别是形状为(2,2),(2,3)的数组,这样a在水平上的两形状为(2,)的元素就可以和b上的两个(3,)分别进行水平堆叠。


    2-D
In [33]: a = np.arange(4).reshape(2,2)
In [34]: b = np.arange(6).reshape(2,3)

In [35]: np.hstack((a,b))
Out[35]:
array([[0, 1, 0, 1, 2],
       [2, 3, 3, 4, 5]])

  如果在2-D以上叠加时,其实和2-D并无区别。我们可以把更高维度抽象为一个元素,只要这个元素的形状相同就能够使得其在水平上堆叠。总的来说在更高维度上水平堆叠时,仅需保持除axis=1轴外形状相同即可。

In [5]: b = np.arange(24).reshape(2,3,4)
In [6]: a = np.arange(16).reshape(2,2,4)

In [7]: np.hstack((a,b))
Out[7]:
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15],
        [12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])


vstack

np.vstack(tup)
  vstack方法等价于concatenate方法沿着axis=0级联。

  • 1-D
      通俗理解,vstack的意思是vertically stack即垂直堆叠。假设对于两个形状分别为(3,)和(2,)的1-D数组,我们想要垂直堆叠是做不到的。
    1-D


      因此只有形状相同的情况下,两个数组才能垂直堆叠在一起。就像下图中的abnp.vasack((a,b))后就得到下右图所示现状为(2,3)的数组。
    1-D


In [9]: a = np.arange(3)
In [10]: b = np.arange(3)

In [11]: np.vstack((a,b))
Out[11]:
array([[0, 1, 2],
       [0, 1, 2]])

  • 2-D及以上
      在垂直堆叠时,可对比hstack水平堆叠。我们可以将更高维度就行抽象,除axis=0外,只要高层保持形状相同便可以进行堆叠。
# 对于二维
In [4]: a = np.arange(6).reshape(2,3)
In [5]: b = np.arange(9).reshape(3,3)

In [6]: np.vstack((a,b))
Out[6]:
array([[0, 1, 2],
       [3, 4, 5],
       [0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

# 对于三维
In [7]: b = np.arange(9).reshape(3,3,1)
In [8]: a = np.arange(6).reshape(2,3,1)

In [9]: np.vstack((a,b))
Out[9]:
array([[[0],
        [1],
        [2]],

       [[3],
        [4],
        [5]],

       [[0],
        [1],
        [2]],

       [[3],
        [4],
        [5]],

       [[6],
        [7],
        [8]]])


dstack

np.dstack(tup)
  dstack就是depth stack,是沿着axis=2进行堆叠的。
  对于1-D形状为(M,)的数组,会被重塑为(1,M,1)的形状,来进行深度堆叠,对于2-D形状为(M.N)的数组则会被重塑为(M,N,1)的形状,来进行深度堆叠。

# 对于一维
In [14]: a = np.arange(3)
In [15]: b = np.arange(3)

In [16]: np.dstack((a,b))
Out[16]:
array([[[0, 0],
        [1, 1],
        [2, 2]]])

# 对于二维
In [18]: b = np.arange(6).reshape(2,3)
In [19]: a = np.arange(6).reshape(2,3)

In [20]: np.dstack((a,b))
Out[20]:
array([[[0, 0],
        [1, 1],
        [2, 2]],

       [[3, 3],
        [4, 4],
        [5, 5]]])


总结

  这三个函数对三维的阵列是最有意义的。例如,对于具有高度(第一轴),宽度(第二轴)和深度(第三轴)的数据。我们只需要记住vstackhstackdstack是分别对第一、二、三轴进行操作。
  读者如果处理多维数据,建议使用函数concatenatestackblock提供的更常规的堆叠和串联操作。



拆分

方法 含义
split 将一个数组拆分为多个子数组。
array_split 将一个数组拆分为大小相等或近似相等的多个子数组。
hsplit 水平(按列)将数组拆分为多个子数组。
vsplit 垂直(逐行)将数组拆分为多个子数组。
dsplit 沿第3轴(深度)将数组拆分为多个子数组。


split

np.split(ary, indices_or_sections, axis=0)
  如果indices_or_sections是整型N,则数组arr会被切分成N整份。如果不够切分则报错。

In [5]: a = np.arange(8)
 
 # 切割成两份,够切
In [6]: np.split(a,2)
Out[6]: [array([0, 1, 2, 3]), array([4, 5, 6, 7])]

# 切割成三份,不够切 报错
In [7]: np.split(a,3)
ValueError: array split does not result in an equal division

  如果indices_or_sections是1-D数组,则会根据数组段来进行切分,举个例子;如果indices_or_sections的值为[2,5],则会将arr分为arr[:2]arr[2:5]arr[5:]三个部分。当超出数组索引范围时,则会以空数组替代。

In [9]: a = np.arange(10)

# 未超出数组索引范围
In [10]: np.split(a,[2,5])
Out[10]: [array([0, 1]), array([2, 3, 4]), array([5, 6, 7, 8, 9])]

# 超出数组索引范围
In [13]: np.split(a,[2,5,10])
Out[13]:
[array([0, 1]),
 array([2, 3, 4]),
 array([5, 6, 7, 8, 9]),
 array([], dtype=int32)]


array_split

np.array_split(ary, indices_or_sections, axis=0)
  与split不同的是,array_splitindices_or_sections参数只能为整型,且不够切分时N等份时,最后一块则以len(arr)%N保留,它的并无差别。

# 一维
In [4]: a = np.arange(8)

In [5]: np.array_split(a,3)
Out[5]: [array([0, 1, 2]), array([3, 4, 5]), array([6, 7])]

#二维
In [8]: b = np.arange(8).reshape(2,4)

In [9]: np.array_split(b,2,axis = 1)
Out[9]:
[array([[0, 1],
        [4, 5]]), 
 array([[2, 3],
        [6, 7]])]


hsplit、vsplit、dsplit

  • hsplit
    np.hsplit(ary, indices_or_sections)
      hsplit是沿着axis=1进行切分。indices_or_sections详细切分使用过程与split相似。
In [24]: a = np.arange(12).reshape(2,6)

# 够切,则切
In [25]: np.hsplit(a,3)
Out[25]:
[array([[0, 1],
        [6, 7]]), array([[2, 3],
        [8, 9]]), array([[ 4,  5],
        [10, 11]])]
# 不够,则报错
In [26]: np.hsplit(a,4)
ValueError: array split does not result in an equal division

# 按数组切分
In [28]: np.hsplit(a,[3,5])
Out[28]:
[array([[0, 1, 2],
        [6, 7, 8]]), 
 array([[ 3,  4],
        [ 9, 10]]), 
 array([[ 5],
 		[11]])]

  • vsplit
    hsplit类似,这里不过多赘述。
In [29]: a = np.arange(12).reshape(2,6)

# 够切,则切
In [30]: np.vsplit(a,2)
Out[30]: [array([[0, 1, 2, 3, 4, 5]]), array([[ 6,  7,  8,  9, 10, 11]])]
# 不够,则报错
In [31]: np.vsplit(a,3)
ValueError: array split does not result in an equal division

# 按数组切分
In [32]: np.vsplit(a,[0,1])
Out[32]:
[array([], shape=(0, 6), dtype=int32),
 array([[0, 1, 2, 3, 4, 5]]),
 array([[ 6,  7,  8,  9, 10, 11]])]

  • dsplit
    hsplit类似,这里不过多赘述。
In [37]: a = np.arange(20).reshape(2,2,6)

# 够切,则切
In [38]: np.dsplit(a,2)
Out[38]:
[array([[[ 0,  1,  2],
         [ 6,  7,  8]],
        [[12, 13, 14],
         [18, 19, 20]]]), 
 array([[[ 3,  4,  5],
         [ 9, 10, 11]],
        [[15, 16, 17],
         [21, 22, 23]]])]
# 不够,则报错
In [39]: np.dsplit(a,4)
ValueError: array split does not result in an equal division

# 按数组切分
In [40]: np.dsplit(a,[1,2])
Out[40]:
[array([[[ 0],
         [ 6]],
        [[12],
         [18]]]), 
 array([[[ 1],
         [ 7]],
        [[13],
         [19]]]), 
 array([[[ 2,  3,  4,  5],
         [ 8,  9, 10, 11]],
        [[14, 15, 16, 17],
         [20, 21, 22, 23]]])]
发布了19 篇原创文章 · 获赞 19 · 访问量 3607

猜你喜欢

转载自blog.csdn.net/qq_36733722/article/details/102961548