Numpy 一维、二维数组、size/dtype/shape属性、数组函数arange/linspace/logspace /diag/zeros/ones/random 、多维数组索引和筛选)

参考: https://gitbook.cn/gitchat/column/undefined/topic/5e3bceadec8d9033cf924665

打开 IPython ,创建 Python 的列表 a 对象。然后,使用列表生成式,创建一个元素都为原来两倍的新列表 a2,并统计这一行的用时为 921 ms。

In [95]: a =list(range(10000000))

In [96]: %time b = [i*2 for i in a]
Wall time: 921 ms

使用 NumPy ,创建同样大小和取值的数组 na。然后,对每个元素乘以 2,返回一个新数组 na2,用时为 31 ms。

In [90]: import numpy as np

In [93]: na = np.array(range(10000000))

In [94]: %time na = na*2
Wall time: 31.3 ms

可以看到,完成同样的都对元素乘以 2 的操作, NumPyPython 快了 30 倍之多。

NumPy 计算为什么这么快呢?

  • Pythonlist 是一个通用结构。它能包括任意类型的对象,并且是动态类型。
  • NumPyndarray 是静态、同质的类型,当 ndarray 对象被创建时,元素的类型就确定。

由于是静态类型,所以 ndarray 间的加、减、乘、除用 CFortran 实现才成为可能,所以运行起来就会更快。根据官网介绍,底层代码用 C 语言和 Fortran 语言实现,实现性能无限接近 C 的处理效率。

1. 创建 Numpy 数组

1.1 一维数组 array

In [99]: import numpy as np

In [101]: np.array([1,2,3,4])
Out[101]: array([1, 2, 3, 4])

1.2 二维数组 array

In [102]: np.array([[1,2], [3,4]])
Out[102]: 
array([[1, 2],
       [3, 4]])

一维数组和二维数组的类型都为 numpy.ndarray

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

In [104]: b = np.array([[1,2], [3,4]])

In [105]: type(a)
Out[105]: numpy.ndarray

In [106]: type(b)
Out[106]: numpy.ndarray

1.3 arange 数组

In [22]: r = np.arange(1, 10, 1)

In [23]: r
Out[23]: array([1, 2, 3, 4, 5, 6, 7, 8, 9])

arange() 的第一个值代表开始值,第二个值代表终值(不包括这个值),最后一个值代表步长(间隔),如 arange(1,10,1) 代表一个从 0-9,步长为 1 的数组。

1.4 linspace 数组

返回 1 和 10 之间的 8 个元素。

In [110]: np.linspace(1, 10, 8)
Out[110]: 
array([ 1.        ,  2.28571429,  3.57142857,  4.85714286,  6.14285714,
        7.42857143,  8.71428571, 10.        ])

In [111]: np.linspace(1, 10, 8)
Out[111]: 
array([ 1.        ,  2.28571429,  3.57142857,  4.85714286,  6.14285714,
        7.42857143,  8.71428571, 10.        ])

In [112]: 

对于 linspace() ,它的前两个值和 arange() 一样,代表开始值和终值,但有个区别是 linspace() 默认包括终值,如果你不想包括终值,加上 endpoint = False 即可,对于第三个值它是指元素的个数,这个和 arange 不一样,一定不要混淆。

1.5 组合 ndarray 对象

如下创建一个 ndarray 对象 a

In [112]: a = np.arange(10).reshape(2, -1)

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

找出 a 中大于 4 的元素索引,使用 where 方法,返回一个元组,带有 2 个 ndarray 对象,分别表示大于 4 的元素第一维、第二维度中的位置:

In [114]: np.where(a>4)
Out[114]: (array([1, 1, 1, 1, 1], dtype=int64), array([0, 1, 2, 3, 4], dtype=int64))

我们把它拼接为一个 ndarray 对象:

In [115]: np.array(np.where(a>4))
Out[115]: 
array([[1, 1, 1, 1, 1],
       [0, 1, 2, 3, 4]], dtype=int64)

然后,再转置,使用 np.transpose 方法:

In [117]: np.transpose(x)
Out[117]: 
array([[1, 0],
       [1, 1],
       [1, 2],
       [1, 3],
       [1, 4]], dtype=int64)

In [118]: 

可以很明显的看出 [1, 0] 表示大于 4 的元素在原 ndarray 对象的索引。

2. Numpy 数组属性

2.1 shape 属性

shape 属性返回数组的形状信息,是一个元组对象。

In [118]: a = np.zeros(5)

In [120]: b = np.ones((2, 3))

In [121]: a
Out[121]: array([0., 0., 0., 0., 0.])

In [122]: b
Out[122]: 
array([[1., 1., 1.],
       [1., 1., 1.]])

可以看到 a 是一维的,而 b 是一个 2*3 的数组,打印它们的 shape 信息,可以看到:

In [124]: a.shape
Out[124]: (5,)

In [125]: b.shape
Out[125]: (2, 3)

In [126]: 

2.2 size 属性

size 属性获取数组内元素个数:

In [126]: a.size
Out[126]: 5

In [127]: b.size
Out[127]: 6

In [128]: 

2.3 dtype 属性

dtype 属性获取数组内元素的类型:

In [128]: a.dtype
Out[128]: dtype('float64')

In [129]: b.dtype
Out[129]: dtype('float64')

创建数组时,还可以通过为 dtype 赋值,指定元素类型:

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

In [135]: m.dtype
Out[135]: dtype('int32')

In [136]: m = np.array([1,2,3], dtype='float')

In [137]: m.dtype
Out[137]: dtype('float64')

dtype 更多取值: intcomplexboolobject ,还可以显示的定义数据位数的类型,如: int64int16float128complex128

3. 数组函数

3.1 arange 函数

起始点,终点,步长;不包括终点。

In [138]: np.arange(1, 10, 2)
Out[138]: array([1, 3, 5, 7, 9])

In [139]: 

3.2 linspace 函数


起始点,终点,分割份数;包括终点。

In [139]: np.linspace(1, 10, 7)
Out[139]: array([ 1. ,  2.5,  4. ,  5.5,  7. ,  8.5, 10. ])

In [140]: 

3.3 logspace 函数

创建以 e 为底,指数为 1,2,…,10 的数组:

In [140]: np.logspace(1, 10, 3)
Out[140]: array([1.00000000e+01, 3.16227766e+05, 1.00000000e+10])

In [141]: 

3.4 diag 对角函数

创建对角数组:

In [141]: np.diag([1,2,3,4])
Out[141]: 
array([[1, 0, 0, 0],
       [0, 2, 0, 0],
       [0, 0, 3, 0],
       [0, 0, 0, 4]])

主对角线偏移 1 的数组:

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

In [143]: 

3.5 zeros 函数

创建一个全零的数组,接受参数为数组的维度

In [143]: np.zeros(3)
Out[143]: array([0., 0., 0.])

In [145]: np.zeros((3,4))
Out[145]: 
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])

In [146]: np.zeros((2,3,4))
Out[146]: 
array([[[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]],

       [[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]]])

In [147]: 

3.6 ones 函数

创建一个全 1 的数组

In [147]: np.ones(3)
Out[147]: array([1., 1., 1.])

In [148]: np.ones((2,3))
Out[148]: 
array([[1., 1., 1.],
       [1., 1., 1.]])

In [149]: np.ones((2,3,1))
Out[149]: 
array([[[1.],
        [1.],
        [1.]],

       [[1.],
        [1.],
        [1.]]])

In [150]: 

3.7 random 随机数组

生成 0~1、shape 为 (2,3) 的随机数数组:

In [151]: np.random.rand(2,3)
Out[151]: 
array([[0.50761977, 0.73557945, 0.84018083],
       [0.1117079 , 0.02225728, 0.51466307]])

In [152]: 

随机数组函数

4. 多维索引和筛选

4.1 二维数组

In [37]: a = np.arange(25).reshape(5,5)

In [38]: a
Out[38]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

In [39]: a[0]
Out[39]: array([0, 1, 2, 3, 4])

In [40]: a[1]
Out[40]: array([5, 6, 7, 8, 9])


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

In [47]: a[1:3]
Out[47]: 
array([[ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

In [48]: a[0][0]
Out[48]: 0

In [53]: a[0,0]
Out[53]: 0

In [51]: 

a[0][0]a[0,0] 是等价的。

4.2 三维数组

NumPy 索引,功能强大,不仅支持切片操作,还支持布尔型按条件筛选操作。

In [152]: m = np.arange(18).reshape(2,3,3)

In [153]: n = np.arange(18)

In [154]: m
Out[154]: 
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]]])

: 表示此维度的所有元素全部获取:

In [155]: m[:,1:2,:]
Out[155]: 
array([[[ 3,  4,  5]],

       [[12, 13, 14]]])

In [156]: m[:,1:2,:1]
Out[156]: 
array([[[ 3]],

       [[12]]])

In [157]: 

按照维度赋值:

In [157]: m[:,0,:] = -2

In [158]: m
Out[158]: 
array([[[-2, -2, -2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[-2, -2, -2],
        [12, 13, 14],
        [15, 16, 17]]])

In [159]: m[:,:,1]
Out[159]: 
array([[-2,  4,  7],
       [-2, 13, 16]])

In [160]: 

判断上面切片 m[:,:,0] 中大于 5 的元素,写法简洁,无需写 for 循环。

In [160]: m
Out[160]: 
array([[[-2, -2, -2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[-2, -2, -2],
        [12, 13, 14],
        [15, 16, 17]]])

In [161]: m[m>5]
Out[161]: array([ 6,  7,  8, 12, 13, 14, 15, 16, 17])

In [162]: 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值