numpy——进阶篇

相关文章

numpy——基础篇



tile(平铺)

tile(A,resp)
  通过重复resp结构次数来构造数组A。就如tile单词的意思一样,可以想象A是一块砖,以resp样式来就行铺设。

In [1]: import numpy as np

In [2]: a = np.array([1,2,3])

# 如果为数字,则在A基础上上重复
In [3]: np.tile(a,2)
Out[3]: array([1, 2, 3, 1, 2, 3])
# 元组(2,1)表示构建一个(2,1)的数组,并以A填充,下同
In [4]: np.tile(a,(2,1))
Out[4]:
array([[1, 2, 3],
       [1, 2, 3]])

In [5]: np.tile(a,(2,2))
Out[5]:
array([[1, 2, 3, 1, 2, 3],
       [1, 2, 3, 1, 2, 3]])

In [6]: np.tile(a,(1,2))
Out[6]: array([[1, 2, 3, 1, 2, 3]])

In [7]: np.tile(a,(3,2,1))
Out[7]:
array([[[1, 2, 3],
        [1, 2, 3]],

       [[1, 2, 3],
        [1, 2, 3]],

       [[1, 2, 3],
        [1, 2, 3]]])

  当resp小于原本A的维度时,则会在保留A原有维度。

In [10]: b=np.arange(6).reshape([3,2,1])

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

       [[2],
        [3],
        [2],
        [3]],

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


Masked Arrays

什么是Masked Arrays?

  数组在有的时候可能会存在无效的或者缺失值。当在这些数组上做一些操作时,我们希望去以我们希望的数值去填充掩盖这些无效的数据。

函数结构

  函数结构如下:
x = MaskedArray( data, mask=nomask, dtype=None, copy=False, subok=True, ndmin=0, fill_value=None, keep_mask=True, hard_mask=None, shrink=True, order=None)

常用参数说明
data数组类型的输入数据
mask数组形状的布尔类型的掩码
dtype输出数组元素的数据类型
copy是否复制输入数组的数据(默认False 为引用)
fill_value必要时用于填充掩码值的值。如果为None,则使用基于数据类型的默认值。
keep_mask将“ mask”与输入数据的掩码(如果有的话)组合(真),将“ mask”用于输出(假)。默认值为True。
hard_msak是否使用强mask(不能取消mask),默认(False)不使用。

创建MaskedArray

  我们可以通过np.ma.masked_arraynp.ma.MaskedArray创建带有掩码的MaskedArray数组。

In [1]: import numpy as np
In [3]: a = np.array([1,2,3,4,np.nan,6,7,np.nan,9])
In [4]: mask_a = np.ma.masked_array(a,np.isnan(a))
In [5]: mask_a
Out[5]:
masked_array(
	data=[1.0, 2.0, 3.0, 4.0, --, 6.0, 7.0, --, 9.0],
	mask=[False, False, False, False,  True, False, False,  True, False],
    fill_value=1e+20)


copy

  copy,是否复制输入数组的数据(默认False 为引用)

# 默认是False,为引用
# 可以看到当mask_a修改时,a的值也同时修改了
In [3]: a
Out[3]: array([0, 1, 2, 3, 4])
In [4]: mask_a = np.ma.masked_array(a, a < 2)
In [5]: mask_a[0] = 5
In [6]: mask_a
Out[6]:
masked_array(
		data=[5, --, 2, 3, 4],
        mask=[False,  True, False, False, False],
        fill_value=999999)
In [7]: a
Out[7]: array([5, 1, 2, 3, 4])

# 现在我们将设为True,为a的副本
# 可以看到当mask_a修改时,a的值没有修改
In [8]: mask_a = np.ma.masked_array(a, a < 2,copy = True)
In [9]: mask_a[0] = 4
In [10]: mask_a
Out[10]:
masked_array(
		 data=[4, --, 2, 3, 4],
         mask=[False,  True, False, False, False],
         fill_value=999999)
In [11]: a
Out[11]: array([5, 1, 2, 3, 4])


fill_value

  设置默认填充值。填充值不会参与计算

In [14]: a = np.arange(5)
In [15]: mask_a = np.ma.masked_array(a, a< 2, fill_value= 2)
In [16]: mask_a
Out[16]:
masked_array(
		 data=[--, --, 2, 3, 4],
         mask=[ True,  True, False, False, False],
         fill_value=2)
In [17]: mask_a.mean()
Out[17]: 3.0
In [18]: mask_a.filled()
Out[18]: array([2, 2, 2, 3, 4])


clip

clip(a, a_min, a_max, out=None, **kwargs)
  裁剪(限制)数组中的值。
  使用clip函数可以控制值的范围,将其限制在最大最小区间内,对于小于最小值和大于最大值的项以设置的最大最小值替代。

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

In [13]: a
Out[13]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [14]: a.clip(3,7)
Out[14]: array([3, 3, 3, 3, 4, 5, 6, 7, 7, 7])

In [15]: np.clip(a,3,7)
Out[15]: array([3, 3, 3, 3, 4, 5, 6, 7, 7, 7])

In [16]: a
Out[16]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [17]: np.clip(a,3,7,out=a)
Out[17]: array([3, 3, 3, 3, 4, 5, 6, 7, 7, 7])

  也可以使用多个不同的最大最小值结合限制数组

In [27]: a
Out[27]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

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


合并

方法含义
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)的样式。
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} [M],我们可以通过四小块构成: [ A B C D ] \begin{bmatrix} A&B\\ C&D \end{bmatrix} [ACBD]
在这里插入图片描述

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)。

  • 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]]])]


eye和identity(单位阵)

eye(N, M=None, k=0, dtype=<class 'float'>, order='C')
  返回一个二维数组,对角线上是1,其它地方为0。当k为正上移对象线,k为负时下移对角线。

In [3]: np.eye(2)
Out[3]:
array([[1., 0.],
       [0., 1.]])
In [4]: np.eye(4,k=1)
Out[4]:
array([[0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.],
       [0., 0., 0., 0.]])

In [5]: np.eye(4,k=-1)
Out[5]:
array([[0., 0., 0., 0.],
       [1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.]])


identity(n, dtype=None)
  与eye不同的是identity仅能创建对角矩阵。

In [10]: np.identity(3)
Out[10]:
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])


set_printoptions(设置输出)

set_printoptions(precision=None, threshold=None, edgeitems=None, linewidth=None, suppress=None, nanstr=None, infstr=None, formatter=None, sign=None, floatmode=None, *, legacy=None)
  设置浮点数的精确度。

In [2]: np.set_printoptions(precision= 5)

In [3]: np.array([1.254831,0.235482])
Out[3]: array([1.25483, 0.23548])

  折叠数组,默认值为1000,当数组中的元素超过1000时就会被折叠。下面设置treshold=7,即超过7项的数组会被折叠。当设置比6小的数时并不一定会折叠,这是因为折叠至少需要6个数

In [24]: np.set_printoptions(threshold= 7)

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

In [26]: np.arange(8)
Out[26]: array([0, 1, 2, ..., 5, 6, 7])

# 当设置的折叠数过小时
In [30]: np.set_printoptions(threshold= 5)

In [31]: np.arange(6)
Out[31]: array([0, 1, 2, 3, 4, 5])










未完待续 不定期更新

  • 6
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值