💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
主要介绍Python中的Numpy入门教程,着重讲解了矩阵中的数组操作。 [TOC] # Numpy是什么 NumPy是Python中的一个运算速度非常快的一个数学库,一般与Scipy、matplotlib一起使用,它非常重视数组。它允许你在Python中进行向量和矩阵计算,并且由于许多底层函数实际上是用C编写的,因此你可以体验在原生Python中永远无法体验到的速度。 > NumPy绝对是科学Python成功的关键之一,如果你想要进入Python中的数据科学和/或机器学习,你就要必须学习它。 在以下的代码示例中,总是先导入了numpy: ``` >>> import numpy as np >>> print(np.version.version) 1.14.0 ``` # 数组基础 NumPy围绕这些称为数组的事物展开,它被称之为`ndarrays`。使用NumPy提供的这些数组,我们就可以以闪电般的速度执行各种有用的操作,如矢量和矩阵、线性代数等数学运算!, > 多维数组的类型是:`numpy.ndarray`。 ``` >>>data = [1,2,3,4] >>>print(type(data)) <class 'list'> >>>array=np.array(data) >>>print(type(array)) <class 'numpy.ndarray'> ``` ## 使用NumPy表示向量 以list或tuple变量为参数产生一维数组: ``` >>> print(np.array([1,2,3,4])) [1 2 3 4] >>> print(np.array((1.2,2,3,4))) [ 1.2 2. 3. 4. ] >>> print(type(np.array((1.2,2,3,4)))) <type 'numpy.ndarray'> ``` ~~~ # 1D Array a = np.array([0, 1, 2, 3, 4]) b = np.array((0, 1, 2, 3, 4)) c = np.arange(5) d = np.linspace(0, 2*np.pi, 5) print(a) # >>>[0 1 2 3 4] print(b) # >>>[0 1 2 3 4] print(c) # >>>[0 1 2 3 4] print(d) # >>>[ 0. 1.57079633 3.14159265 4.71238898 6.28318531] print(a[3]) # >>>3 ~~~ 上面的代码显示了创建数组的4种不同方法。最基本的方法是将序列传递给NumPy的array()函数; 你可以传递任何序列(类数组),而不仅仅是常见的列表(list)数据类型。 ## 多维数组 以list或tuple变量为元素产生二维数组 ~~~ # MD Array, a = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28 ,29, 30], [31, 32, 33, 34, 35]]) print(a[2,4]) # >>>25 ~~~ 为了创建一个2D(二维)数组,我们传递一个列表的列表(或者是一个序列的序列)给array()函数。如果我们想要一个3D(三维)数组,我们就要传递一个列表的列表的列表,如果是一个4D(四维)数组,那就是列表的列表的列表的列表,以此类推。 > 请注意2D(二维)数组(在我们的朋友空格键的帮助下)是如何按行和列排列的。要索引2D(二维)数组,我们只需引用行数和列数即可。 生成数组的时候,可以指定数据类型,例如numpy.int32, numpy.int16, and numpy.float64等: ``` >>> print(np.array((1.2,2,3,4), dtype=np.int32)) [1 2 3 4] ``` > 浮点数转换int32类型时采用的是截尾操作。 # 常用函数 ## 使用numpy.arange方法 ``` >>> print(np.arange(15)) [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] >>> print(type(np.arange(15))) <class 'numpy.ndarray'> ``` ``` >>> print(np.arange(15).reshape(3,5)) [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14]] >>> print(type(np.arange(15).reshape(3,5))) <class 'numpy.ndarray'> ``` ## 使用numpy.linspace方法 例如,在从1到10中产生10个数: ``` >>> print(np.linspace(1,10,10)) [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.] ``` ## 使用numpy.zeros,numpy.ones,numpy.eye等方法可以构造特定的矩阵 ``` >>> print(np.zeros((3,4))) [[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]] >>> print(np.ones((3,4))) [[1. 1. 1. 1.] [1. 1. 1. 1.] [1. 1. 1. 1.]] >>>print(np.eye(3)) [[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]] ``` 创建一个三维数组: ``` >>>print(np.ones((3,4,5))) [[[1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.]] [[1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.]] [[1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.]]] ``` ## 获取数组的属性: ``` >>> a = np.zeros((2,2,2)) >>> print(a.ndim)   #数组的维数 3 >>> print(a.shape)  #数组每一维的大小 (2, 2, 2) >>> print(a.size)   #数组的元素数 8 >>> print(a.dtype)  #元素类型 float64 >>> print(a.itemsize) #每个元素所占的字节数 8 ``` ## 数组索引,切片,赋值 ``` >>> a = np.array( [[2,3,4],[5,6,7]] ) >>> print a [[2 3 4] [5 6 7]] >>> print a[1,2] 7 >>> print a[1,:] [5 6 7] >>> print a[1,1:2] [6] >>> a[1,:] = [8,9,10] >>> print a [[ 2 3 4] [ 8 9 10]] ``` ## 使用for操作元素 ``` >>> for x in np.linspace(1,3,3): ... print(x) ... 1.0 2.0 3.0 ``` ## 基本的数组运算 先构造数组a、b: ``` >>> a = np.ones((2,2)) >>> b = np.eye(2) >>> print a [[ 1. 1.] [ 1. 1.]] >>> print b [[ 1. 0.] [ 0. 1.]] ``` 数组的加减乘除: ``` >>> print a > 2 [[False False] [False False]] >>> print a+b [[ 2. 1.] [ 1. 2.]] >>> print a-b [[ 0. 1.] [ 1. 0.]] >>> print b*2 [[ 2. 0.] [ 0. 2.]] >>> print (a*2)*(b*2) [[ 4. 0.] [ 0. 4.]] >>> print b/(a*2) [[ 0.5 0. ] [ 0. 0.5]] >>> print (a*2)**4 [[ 16. 16.] [ 16. 16.]] ```  使用数组对象自带的方法: ``` >>> a.sum() 4.0 >>> a.sum(axis=0) #计算每一列(二维数组中类似于矩阵的列)的和 array([ 2., 2.]) >>> a.min() 1.0 >>> a.max() 1.0 ``` 使用numpy下的方法: ``` >>> np.sin(a) array([[ 0.84147098, 0.84147098], [ 0.84147098, 0.84147098]]) >>> np.max(a) 1.0 >>> np.floor(a) array([[ 1., 1.], [ 1., 1.]]) >>> np.exp(a) array([[ 2.71828183, 2.71828183], [ 2.71828183, 2.71828183]]) >>> np.dot(a,a) ##矩阵乘法 array([[ 2., 2.], [ 2., 2.]]) ``` ## 合并数组 使用numpy下的vstack和hstack函数: ``` >>> a = np.ones((2,2)) >>> b = np.eye(2) >>> print np.vstack((a,b)) [[ 1. 1.] [ 1. 1.] [ 1. 0.] [ 0. 1.]] >>> print np.hstack((a,b)) [[ 1. 1. 1. 0.] [ 1. 1. 0. 1.]] ``` 看一下这两个函数有没有涉及到浅拷贝这种问题: ``` >>> c = np.hstack((a,b)) >>> print(c) [[ 1. 1. 1. 0.] [ 1. 1. 0. 1.]] >>> a[1,1] = 5 >>> b[1,1] = 5 >>> print(c) [[ 1. 1. 1. 0.] [ 1. 1. 0. 1.]] ``` 可以看到,a、b中元素的改变并未影响c。 ## 深拷贝数组 数组对象自带了浅拷贝和深拷贝的方法,但是一般用深拷贝多一些: 复制代码代码如下: ``` >>> a = np.ones((2,2)) >>> b = a >>> b is a True >>> c = a.copy() #深拷贝 >>> c is a False ``` ## 基本的矩阵运算 转置: ``` >>> a = np.array([[1,0],[2,3]]) >>> print(a) [[1 0] [2 3]] >>> print(a.transpose() ) [[1 2] [0 3]] ``` 迹: ``` >>> print(np.trace(a) ) 4 ``` numpy.linalg模块中有很多关于矩阵运算的方法: ``` >>> import numpy.linalg as nplg ``` 特征值、特征向量: ``` >>> print(nplg.eig(a) ) (array([ 3., 1.]), array([[ 0. , 0.70710678], [ 1. , -0.70710678]])) ```