numpy库

简介

NumPy(Numerical Python)是Python中的一个科学计算程序包。它提供对维数组对象,许多从多维数组对象衍生出来的对象,例如掩膜数组和矩阵,还有很多快速操作数组的方法,包括数值、逻辑、形状操作、排序、选择、I\O、离散傅里叶变换、基本线性代数、基本统计操作。随机模拟等等。

NumPy的核心是ndarray对象,它是一个封装的多维数组,里面元素类型是单一的,为了提高性能,许多操作都是在C预编译执行后进行的,它是不同于Python内置的序列类型的 :

  • NumPy数组在创建时大小是固定的,改变它的大小会创建一个新的数组并删除原来的数组
  • NumPy要求数组里面的元素类型是一致的,这样在内存中大小也是一致的,通过创建对象数组,可以让数组有不同的元素
  • NumPy在操作很长的数据序列时可以体现出它的优越性

NumPy使用C预编译来提高性能,优越于直接使用Python的内置类型

基础

NumPy的核心对象是所谓数组,使用元组作为它的索引,元组里面的元素是整型的,在NumPy中维度叫做轴,下面这个数组有两个轴,第一个轴长度是2,第二个轴长度是3

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

 NumPy中的数组类叫做ndarray,经常用别名称呼它,它不同于Python中的数组,后者只有一个维度,下面是这个类的一些属性

ndarray.ndim

是数组轴的数量,也就是它的维度,将数组的形式类比矩阵,一维矩阵的轴数是1,二维矩阵的轴数是2,对于二维矩阵,第一个轴就是它的行数,第二个轴就是它的列数

ndarray.shape

它表示数组的形状,是一个元组,元组的每一个元素指明数组的一个维度,元组的长度就是数组的维数ndim

ndarray.size

数组中元素的总数,等于形状元组shape每一个元素的乘积

ndarray.dtype

描述数组元素的类型,可以使用Python内置的数据类型,亦可以使用NumPy程序包带的数据类型

ndarray.itemsize

数组元素类型的长度(以字节为单位)

ndarray.data

这是一个包含数组所有元素的缓冲区,一般不用,直接用索引来操作

创建数组

可以用array方法创建数组,将Python内置类型的列表或者元组作为参数传递给array方法,注意不要出错

a = np.array(1,2,3,4)    # WRONG
a = np.array([1,2,3,4])  # RIGHT
>>>>>> b = np.array([(1.5,2,3), (4,5,6)])
>>> b
array([[ 1.5,  2. ,  3. ],
       [ 4. ,  5. ,  6. ]])

在创建数组时,也可以显式的指定数组元素的类型,例如:

>>> c = np.array( [ [1,2], [3,4] ], dtype=complex )
>>> c
array([[ 1.+0.j,  2.+0.j],
       [ 3.+0.j,  4.+0.j]])

一般数组里面的元素开始是不知道的,但是它的大小和尺寸是知道的,所以可以这样创建,zeros,ones,empty方法默认元素类型是float64:

>>> np.zeros( (3,4) )
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])
>>> np.ones( (2,3,4), dtype=np.int16 )                # dtype can also be specified
array([[[ 1, 1, 1, 1],
        [ 1, 1, 1, 1],
        [ 1, 1, 1, 1]],
       [[ 1, 1, 1, 1],
        [ 1, 1, 1, 1],
        [ 1, 1, 1, 1]]], dtype=int16)
>>> np.empty( (2,3) )                                 # uninitialized, output may vary
array([[  3.73603959e-262,   6.02658058e-154,   6.55490914e-260],
       [  5.30498948e-313,   3.14673309e-307,   1.00000000e+000]])

也可以使用full函数,这个函数第一个参数指定了要生成的数组的尺寸,第二个参数指定了生成的数组中元素的类型

np.full(m, 1.0)    # 当数组时一维时,第一个参数就是数组的长度

也可以使用随机数的方法生成一个数组:randn是指从正态分布曲线中选择点,点的数量由m参数指定

np.random.seed(0)     #这句代码是设置随机数种子的值,不同的随机数种子对应着不同的随机数序列
np.random.randn(m)

NumPy还提供方法一个类似range的方法,该方法返回一个数组,第一个参数是起始值,元素小于第二个参数,第三个参数指定步长:

>>> np.arange( 10, 30, 5 )
array([10, 15, 20, 25])
>>> np.arange( 0, 2, 0.3 )                 # it accepts float arguments
array([ 0. ,  0.3,  0.6,  0.9,  1.2,  1.5,  1.8])

当arange方法的参数是浮点类型时可能会导致得到的数组不精确,因此使用一个更好的方法linspace,它的第三个参数是我们需要的元素的数量,而不是步长:

>>> from numpy import pi
>>> np.linspace( 0, 2, 9 )                 # 9 numbers from 0 to 2
array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ,  1.25,  1.5 ,  1.75,  2.  ])
>>> x = np.linspace( 0, 2*pi, 100 )        # useful to evaluate function at lots of points
>>> f = np.sin(x)

打印数组

用矩阵的形式打印,第一行是第一维:

>>> a = np.arange(6)                         # 1d array
>>> print(a)
[0 1 2 3 4 5]
>>>
>>> b = np.arange(12).reshape(4,3)           # 2d array
>>> print(b)
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
>>>
>>> c = np.arange(24).reshape(2,3,4)         # 3d array
>>> print(c)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]
 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

当数组太长时,只显示两头的部分元素,中间的用省略号替代,如果想显示完整需要添加一个方法:

>>> print(np.arange(10000))
[   0    1    2 ..., 9997 9998 9999]
>>>
>>> print(np.arange(10000).reshape(100,100))
[[   0    1    2 ...,   97   98   99]
 [ 100  101  102 ...,  197  198  199]
 [ 200  201  202 ...,  297  298  299]
 ...,
 [9700 9701 9702 ..., 9797 9798 9799]
 [9800 9801 9802 ..., 9897 9898 9899]
 [9900 9901 9902 ..., 9997 9998 9999]]
>>> np.set_printoptions(threshold=np.nan)

基本操作

对数组的算数操作将会生成一个新的数组,参考下面的用法:

>>> a = np.array( [20,30,40,50] )
>>> b = np.arange( 4 )
>>> b
array([0, 1, 2, 3])
>>> c = a-b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
>>> 10*np.sin(a)
array([ 9.12945251, -9.88031624,  7.4511316 , -2.62374854])
>>> a<35
array([ True, True, False, False])

在NumPy中,元素的乘法使用*,矩阵的乘法使用@操作符或者使用一个方法dot:

>>> A = np.array( [[1,1],
...             [0,1]] )
>>> B = np.array( [[2,0],
...             [3,4]] )
>>> A * B                       # elementwise product
array([[2, 0],
       [0, 4]])
>>> A @ B                       # matrix product
array([[5, 4],
       [3, 4]])
>>> A.dot(B)                    # another matrix product
array([[5, 4],
       [3, 4]])

在Numpy中矩阵的转置这样实现:

p = np.arange([2,6,8,4])
q = p.T

一些操作例如+=和*=只会对原来的数组修饰,并不会产生新的数组,这不同于前面的算数操作,下面的例子不仅体现出了这一点还体现出,int向float类型的类型转换时隐式的,但是float向int类型的类型转换会报错

>>> a = np.ones((2,3), dtype=int)
>>> b = np.random.random((2,3))    #用两个random函数,表示随机生成(2,3)这个尺寸的矩阵,元素范围是(0,1)
>>> a *= 3
>>> a
array([[3, 3, 3],
       [3, 3, 3]])
>>> b += a
>>> b
array([[ 3.417022  ,  3.72032449,  3.00011437],
       [ 3.30233257,  3.14675589,  3.09233859]])
>>> a += b                  # b is not automatically converted to integer type
Traceback (most recent call last):
  ...
TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind'

当操作不同类型的数组时,生成的数组中的元素类型会向上转换,也就是使用更精确的类型

>>>>>> a = np.ones(3, dtype=np.int32)
>>> b = np.linspace(0,pi,3)
>>> b.dtype.name
'float64'
>>> c = a+b
>>> c
array([ 1.        ,  2.57079633,  4.14159265])
>>> c.dtype.name
'float64'
>>> d = np.exp(c*1j)
>>> d
array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
       -0.54030231-0.84147098j])
>>> d.dtype.name
'complex128'

许多一维操作,例如计算数组元素之和,是使用ndarray的类方法的

>>> a = np.random.random((2,3))
>>> a
array([[ 0.18626021,  0.34556073,  0.39676747],
       [ 0.53881673,  0.41919451,  0.6852195 ]])
>>> a.sum()
2.5718191614547998
>>> a.min()
0.1862602113776709
>>> a.max()
0.6852195003967595

默认情况下这些操作应用于整个数组,不用管它的形状,但如果需要对数组的某一个轴操作时,可以为这些方法指定轴名:其中,axis=0表示列方向,axis=1表示行方向,返回的还是一个数组

>>> b = np.arange(12).reshape(3,4)
>>> b
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>>
>>> b.sum(axis=0)                            # sum of each column
array([12, 15, 18, 21])
>>>
>>> b.min(axis=1)                            # min of each row
array([0, 4, 8])
>>>
>>> b.cumsum(axis=1)                         # cumulative sum along each row表示在行方向进行累计,每一个元素值都是它前面的元素值的和
array([[ 0,  1,  3,  6],
       [ 4,  9, 15, 22],
       [ 8, 17, 27, 38]])

常用操作

 NumPy提供常用的数学运算,例如三角函数,exp(以e为底的指数)啥的,还有矩阵的加法,这些方法会生成一个数组作为输出

>>> B = np.arange(3)
>>> B
array([0, 1, 2])
>>> np.exp(B)
array([ 1.        ,  2.71828183,  7.3890561 ])
>>> np.sqrt(B)
array([ 0.        ,  1.        ,  1.41421356])
>>> C = np.array([2., -1., 4.])
>>> np.add(B, C)
array([ 2.,  0.,  6.])

索引、切片、迭代

这些操作只对一维数组有效,和Python中的列表用法很像,如下

>>> a = np.arange(10)**3
>>> a
array([  0,   1,   8,  27,  64, 125, 216, 343, 512, 729])
>>> a[2]
8
>>> a[2:5]
array([ 8, 27, 64])
>>> a[:6:2] = -1000    # equivalent to a[0:6:2] = -1000; from start to position 6, exclusive, set every 2nd element to -1000
>>> a
array([-1000,     1, -1000,    27, -1000,   125,   216,   343,   512,   729])
>>> a[ : :-1]                                 # reversed a
array([  729,   512,   343,   216,   125, -1000,    27, -1000,     1, -1000])
>>> for i in a:
...     print(i**(1/3.))
...
nan
1.0
nan
3.0
nan
5.0
6.0
7.0
8.0
9.0

多维数组每个轴有一个索引,因此可以使用一个与维数一致的元组来访问数组中的每一个确切的元素,对于二维的,先行数后列数,当向得到一行或者一列时可以使用切片的方法

>>> def f(x,y):
...     return 10*x+y
...
>>> b = np.fromfunction(f,(5,4),dtype=int)    #这个函数第一个参数是一个函数,给出了元素值的构造方法,第二个参数是数组的尺寸,第三个参数是数组元素的类型
>>> b
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [20, 21, 22, 23],
       [30, 31, 32, 33],
       [40, 41, 42, 43]])
>>> b[2,3]
23
>>> b[0:5, 1]                       # each row in the second column of b
array([ 1, 11, 21, 31, 41])
>>> b[ : ,1]                        # equivalent to the previous example
array([ 1, 11, 21, 31, 41])
>>> b[1:3, : ]                      # each column in the second and third row of b
array([[10, 11, 12, 13],
       [20, 21, 22, 23]])

当提供的索引小于轴数时,缺失的索引被认为是完整的切片,如下所示:

>>> b[-1]                                  # the last row. Equivalent to b[-1,:]
array([40, 41, 42, 43])

也可以使用···来表示缺失的轴,当x是一个5维数组时

  • x[1,2,...] is equivalent to x[1,2,:,:,:],
  • x[...,3] to x[:,:,:,:,3] and
  • x[4,...,5,:] to x[4,:,:,5,:].
>>> c = np.array( [[[  0,  1,  2],               # a 3D array (two stacked 2D arrays)
...                 [ 10, 12, 13]],
...                [[100,101,102],
...                 [110,112,113]]])
>>> c.shape
(2, 2, 3)
>>> c[1,...]                                   # same as c[1,:,:] or c[1]
array([[100, 101, 102],
       [110, 112, 113]])
>>> c[...,2]                                   # same as c[:,:,2]
array([[  2,  13],
       [102, 113]])

对多维数组的迭代是针对第一个轴实现的,对于二维数组就是行

>>> for row in b:    #每次取出b的一行
...     print(row)
...
[0 1 2 3]
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43]

对多维数组中的每一个元素迭代可以使用flat属性

>>> for element in b.flat:
...     print(element)
...
0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33
40
41
42
43

常用方法

  • np.linalg.nom(theta, error),这个函数会计算theta和error的2范数,也就是求模

以上就是NumPy的基本操作,暂时学习到这里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值