目录
一、 numpy概述
NumPy是Python科学计算的基础软件包,提供多了维数组对象,多种派生对象(掩码数组、矩阵等)以及用于快速操作数组的函数及API,它包括数学、逻辑、数组形状变换、排序、选择、I/O 、离散傅立叶变换、基本线性代数、基本统计运算、随机模拟等。
NumPy是SciPy家族的成员之一。SciPy家族是一个专门应用于数学、科学和工程领域的开源Python生态圈,SciPy家族的核心成员为Matplotlib、SciPy和NumPy,可以概括为MSN这三个字母。
NumPy的核心是多维数组类numpy.ndarray,矩阵类numpy.matrix是多维数组类的派生类。以多维数组类为数据组织结构,NumPy提供了众多的数学、科学和工程函数。NumPy的组织结构如下图所示。
图中红色的两个子模块,numpy.core是NumPy的核心,包含ndarray、 ufuncs和dtypes等,numpy.lib提供NumPy的函数。这个两个子模块是私有的,所有的函数和对象都可以在numpy的命名空间中使用,使用时无需使用子模块名。
除了core和lib外,NumPy的其他常用子模块有:
numpy.random :随机抽样子模块
numpy.ma:掩码数组子模块,用于处理包含无效或丢失的数据的数组
numpy.linalg :线性代数子模块 numpy.fft :离散傅里叶变换子模块
numpy.math :由C标准定义的数学函数子模块
numpy.emath :具有自动域的数学函数子模块
numpy.rec :记录数组子模块,数组元素是多个不同类型的数据的组合,类似结构体
numpy.matrixlib :矩阵类和函数子模块
numpy.ctypeslib :ctypes外部函数接口子模块
numpy.polynomial:多项式子模块
numpy.char:向量化字符串操作子模块
numpy.testing :测试支持子模块
二、 numpy常用配置
2.1 numpy配置显式格式
NumPy提供了一个配置字典,用于指定数据的显式格式或方式,比如精度位数,负数、非数字和无穷大的表示符号,是否使用科学计数法等。使用get_printoptions()可以查看配置字典的默认值:
import numpy as np
print(np.get_printoptions())
#输出
#{'edgeitems': 3, 'threshold': 1000, 'floatmode': 'maxprec', 'precision': 8, 'suppress': False, 'linewidth': 75, 'nanstr': 'nan', 'infstr': 'inf', 'sign': '-', 'formatter': None, 'legacy': False}
"edgeitems": 定义在打印数组时,数组两端显示的元素数量。默认值为3,表示打印数组时只显示数组的前3个元素和最后3个元素,中间的元素会被省略。
"threshold": 定义在数组打印过程中截断显示的元素数量。默认值为1000,当数组的元素数量超过这个阈值时,打印时会省略中间的元素,并显示省略号以表示截断。
"floatmode": 定义浮点数的打印模式。该键的值为"maxprec"
。这意味着浮点数将以最大精度模式进行打印。最大精度模式("maxprec"
)是NumPy中的一种打印选项,它会根据浮点数的实际精度来决定打印的位数。换句话说,它会打印浮点数的所有有效位数,而不是根据固定的精度值来截断或舍入。
"precision": 定义打印浮点数的精度(小数点后的位数)。默认值为8,表示打印浮点数时会显示8位小数。
"suppress": 控制是否抑制小数的科学计数法显示。默认为False,表示不抑制科学计数法,即较大或较小的数字将以科学计数法的形式打印。
"linewidth": 定义打印每行的字符限制数。默认值为75,表示在打印数组时,每行字符的数量限制为75个。当一行字符超过这个限制时,将换行显示。
"nanstr": 定义表示NaN(Not a Number)的字符串。默认为"nan",表示在打印数组时,将使用字符串"nan"来表示NaN值。
"infstr": 定义表示正无穷大的字符串。默认为"inf",表示在打印数组时,将使用字符串"inf"来表示正无穷大的值。 "sign": 控制正数的显示方式。默认为"-",表示在打印数组时,正数前面会显示减号。
"formatter": 定义一个函数或对象来自定义数组的打印格式。在提供的字典中,该键的值为None,表示没有自定义的打印格式。
"legacy": 控制是否使用旧版打印选项。在提供的字典中,该键的值为False,表示不使用旧版打印选项。
2.2 设置警告信息
在数学运算时,如果除数为0就会产生溢出错误,程序会异常中断。不过对NumPy而言,这个结果仅是个无效值(nan),通常不会导致程序中断,只是发出警告信息。如果想要屏蔽这个警告信息,可以使用seterr函数。
a = np.array([2,4,6])
b = np.array([1,0,3])
print(a/b)
[ 2. inf 2.]
D:\PyCharm\pycharmProjects\XPath\Numpy_1.py:6: RuntimeWarning: divide by zero encountered in divide
print(a/b)
屏蔽警告信息:
np.seterr(invalid='ignore')
a = np.array([2,4,6])
b = np.array([1,0,3])
print(a/b)
2.3 numpy支持的数据类型
a = np.array([2,4,6])
print(a.dtype)
b = np.array([1,0,3],dtype='int16')
print(b.dtype)
c = np.array([1+1j,2-7j])
print(c.dtype)
d = np.array([1.1,1.2,1.3])
print(d.dtype)
e = np.array([1,0,1],dtype='bool')
print(e.dtype)
#'''
int32
int16
complex128
float64
bool
'''
2.4 numpy的数组属性
dtype可以查看数组的数据类型,dtype是数组对象的属性之一,除了dtype,NumPy数组还有其他一些属性,常用的有dtype和shape这两个属性,np对象加".属性名"即可输出属性值,这里不在详细解释。
2.5 numpy中的维,秩,轴
维,就是维度,指数组的维数,比如二维,三维。
秩是指数组的维度数。
数组的轴,和笛卡尔坐标系的轴。在对多维数组进行计算时,通过轴规定计算方向。
比如一维数组,类比于一维空间,只有一个轴,那就是0轴;二维数组,类比于二维平面,有两个轴,我们习惯表示成行、列,那么行的方向就是0轴,列的方向就是1轴;三维数组,类比于三维空间,有三个轴,我们习惯表示成层、行、列,那么层的方向就是0轴,行的方向就是1轴,列的方向就是2轴。
以三维数组的求和可以分为分层求和,逐行求和,逐列求和等,就需要用到轴规定计算方向。
a = np.arange(1,65).reshape((4,4,4)) # 3层3行3列的结构
print(np.sum(a)) #全部元素求和
print(np.sum(a,axis=0)) #分层求和 也就是层对应位置的和 消去层
print(np.sum(a,axis=1)) #分行求和 也就是行对应位置的和 消去行
print(np.sum(a,axis=2)) #分列求和 也就是列对应位置的和 消去列
#得到每一层的和
print(np.sum(np.sum(a,axis=1),axis=1))
print(np.sum(np.sum(a,axis=2),axis=1))
2.6 广播和矢量化
广播(broadcast)和矢量化(vectorization),是NumPy最精髓的特性,是NumPy的灵魂。所谓广播,就是将对数组的操作映射到每个数组元素上;矢量化可以理解为代码中没有显式的循环、索引等。NumPy数组最重要的特性是广播和矢量化,体现在性能上,就是接近C语言的运行效率,体现在代码上,则有这样的特点。
广播可以使用数组中每个值加1来体会:
a = np.arange(10)
print(a)
print(a+1)
结果:
[0 1 2 3 4 5 6 7 8 9]
[ 1 2 3 4 5 6 7 8 9 10]
矢量化可以体现在两个数组的加减乘除上:
a = np.arange(10)
a = a + 1
b = np.arange(10,20)
print(b + a)
print(b - a)
print(b / a)
print(b * a)
得到结果:
[11 13 15 17 19 21 23 25 27 29]
[9 9 9 9 9 9 9 9 9 9]
[10. 5.5 4. 3.25 2.8 2.5
2.28571429 2.125 2. 1.9 ]
[ 10 22 36 52 70 90 112 136 162 190]