什么要用Numpy
Python中常用的基本数据结构有很多,通常我们在进行简单的数值存储的时候都会使用list来进行,但是list的缺点在于对于每一个元素都需要有指针和对象,对于数值运算来说,list显然是比较浪费内存和CPU计算时间的。为了弥补这种结构的不足,Numpy诞生了,在Numpy中提供了两种基本的对象:ndarray和ufunc。ndarray是存储单一数据类型的多维数组,ufunc则是能够对数组进行处理的函数。
Numpy的主要特点
具有运算快,节约空间的ndarray,提供数组化的算数运算和高级的广播功能;
使用标准数学函数对整个数组的数据进行快速运算,不需传统的循环编写;
读取/写入磁盘上的阵列数据和操作存储器映像文件的工具;
线性代数,随机数生成,以及傅立叶变换的能力;
生成ndarray的几种方式
从已有数据中创建
# 将列表转换成ndarray import numpy as np list1 = [1.1, 2.2, 3, 4, 5] nd1 = np.array(list1) print(type(nd1)) print(list1)
<class 'numpy.ndarray'> [1.1, 2.2, 3, 4, 5]
# 嵌套列表转换成多维ndarray list2 = [[1.1, 2.2, 3, 4, 5],[7.7, 8.8, 9, 10, 11]] nd2 = np.array(list2) print(type(nd2)) print(list2)
<class 'numpy.ndarray'> [[1.1, 2.2, 3, 4, 5], [7.7, 8.8, 9, 10, 11]]
利用random模块生成ndarray
在numpy的random模块中提供了多种生成随机数的函数,常用的几种如下:
- random() 生成0到1之间的随机数;
- uniform() 生成均匀分布的随机数;
- randn() 生成标准正态的随机数;
- normal() 生成符合正态分布的随机数;
- shuffle() 随机打乱数据的顺序;
- seed() 设置随机数种子
# 使用random生成随机数 import numpy as np nd3 = np.random.random((2, 3)) print(type(nd3)) print(nd3)
<class 'numpy.ndarray'> [[0.56190317 0.17571506 0.73992818] [0.61694656 0.84881069 0.47786533]]
创建特殊的多维数组
import numpy as np # 创建0矩阵 nd4 = np.zeros((3, 3)) # 创建全1矩阵 nd5 = np.ones((3, 3)) # 创建单位矩阵 nd6 = np.eye(3) nd7 = np.identity(3) # 创建对角矩阵:主对角线之外的元素都为0 nd8 = np.diag((1, 2, 3, 4)) # 创建对称矩阵 X = np.mat([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) A = np.triu(X) # 用于提取主对角线元素 nd9 = A + A.T - np.diag((np.diagonal(X))) print(nd9)
[[1 2 3] [2 5 6] [3 6 9]]
# np中还提供了函数可以让我们把生成的数据存储成文件,并通过读取的方式加载数据 import numpy as np nd10 = np.random.random((3, 3)) np.savetxt(X=nd10, fname='./test.txt') nd11 = np.loadtxt('./test.txt') print(nd11)
[[0.24245307 0.61346602 0.38558164] [0.77844911 0.22011088 0.54350789] [0.34898106 0.12912724 0.65936827]]
通过循环的方式创建数组
numpy中提供了arange函数使得我们可以通过循环的方式设置起始位置以及步长来生成数组。
nd12 = np.arange(1, 10, 1) print(nd12)
[1 2 3 4 5 6 7 8 9]
元素的存取
import numpy as np # 一维数组的截取 nd13 = np.random.random((10)) # 获取指定位置的数据 nd13[4] # 获取一段数据 nd13[4:8] # 根据步长获取数据 nd13[4:8:2] # 多维数组的截取 nd14 = np.random.random((5, 5)) # 获取指定位置的数据 nd14[2, 4] # 获取指定区域的数据 nd14[1:4, 1:4] # 根据数值截取数据 nd14[(nd14 > 0.4) & (nd14 < 0.8)] # 获取指定的行和列 print(nd14[:, 3]) # 列 print(nd14[3, :]) # 行
[0.8820414 0.63166344 0.88848099 0.91915532 0.38583446] [0.36635677 0.89179454 0.69437534 0.91915532 0.29375765]
我们除了可以通过指定索引获取数据外,还可以使用choice()函数来随机抽取数据
矩阵的运算
numpy中的linalg模块中提供了很多矩阵运算的函数,主要的函数如下:
- diag():以一维数组的方式返回方阵的对角线元素
- dot():矩阵乘法
- trace():求矩阵的迹(对角线元素的和)
- det():计算矩阵列式
- eig():计算方阵的特征值和特征向量
- inv():计算方阵的逆
- qr():计算qr分解
- svd():计算奇异值分解svd
- solve():解线性方程组Ax=b,其中A为矩阵
- lstsq():Ax=b的最小二乘法求解
数据的合并与展开
在实际应用中我们经常会遇到需要把数据进行合并和展开的情况,接下来让我们看一下如何进行操作。
一维数组的合并
import numpy as np a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) # 使用append函数进行合并 c = np.append(a, b) # 使用concatenate函数进行合并 d = np.concatenate((a, b)) print(c) print(d)
[1 2 3 4 5 6] [1 2 3 4 5 6]
多维数组的合并
import numpy as np a = np.arange(4).reshape(2, 2) b = np.arange(4).reshape(2, 2) # 按行合并 c = np.append(a, b, axis=0) # 按列合并 d = np.append(a, b, axis=1) print(c) print(d)
[[0 1] [2 3] [0 1] [2 3]] [[0 1 0 1] [2 3 2 3]]
矩阵展开
import numpy as np nd = np.arange(6).reshape(2, -1) # 按照列展开 nd1 = nd.ravel("F") # 按照行展开 nd2 = nd.ravel() print(nd1) print(nd2)
[0 3 1 4 2 5] [0 1 2 3 4 5]
常用的数学函数
numpy中也提供了大量的数学函数,并且这些函数的运行速度要比math等库中的函数快很多(具体快多少可以自己实践证明一下),常用的数学函数如下:
- sqrt():计算序列化数据的平方根
- sin(),cos():三角函数
- abs():计算序列化数据的绝对值
- dot():矩阵运算
- log(),log10(),log2():对数函数
- exp():指数函数
- cumsum(),cumproduct():累计求和,求积
- sum():对一个序列化数据进行求和
- mean():计算均值
- median():计算中位数
- std():计算标准差
- var():计算方差
- corrcoef():计算相关系数
广播机制
我们都知道,在进行数学运算的时候,不同形状的矩阵不能进行加减的运算,但是numpy中提供的广播机制让我们能够对不同形状的矩阵进行运算,广播的兼容原则为:
- 对齐尾部维度
- shape相等或者其中shape元素中有一个为1
import numpy as np a = np.arange(10).reshape((5,2)) b = np.arange(2).reshape((1,2)) print(a+b)
[[ 0 2] [ 2 4] [ 4 6] [ 6 8] [ 8 10]]