Python的NumPy包提供了NumPy数组,它是为数组运算,特别是比较大型的数组运算设计的。NumPy包是Python科学计算方面的基础包,也是很重要,必须掌握的一个包。
NumPy包及其安装
NumPy数组在数据输入输出性能和存储效率方面比Python的嵌套列表好很多,一方面,NumPy底层是使用C语言编写的,效率远胜于纯Python代码;另一方面,NumPy使用矢量运算的技术,避免了多重嵌套for循环的使用,极大地提高了计算速度。所以,NumPy非常适用于多维数组的计算,数组越大,优势越明显。NumPy是Python实现数据分析、机器学习、深度学习的基础,SciPy, pandas, scikit-learn和tensorflow等包都是在它的基础上开发出来的。
本书是使用Python官网上下载的软件Python 3.7.7进行介绍的,软件并不包含NumPy模块,所以,使用它们之前需要先进行安装。在DOS命令窗口用pip工具安装它们。
在DOS命令窗口的提示符后键入下面的命令行,安装NumPy。
python –m pip install numpy
安装位置一般在C:\Users\用户名\ AppData\Local\Programs\Python\Python3x下。最后的Python3x对应于Python软件的版本,如果版本为3.7,则为Python37。
创建NumPy数组
在NumPy中创建数组的方法很简单,只需要用逗号间隔数组元素,然后用方括号括起来作为array方法的参数就行了。当然,也可以理解为将一个列表转换为NumPy数组,如
>>> import numpy as np
>>> a=np.array([1,2,3])
>>> print a
array([1, 2, 3])
可以使用numpy.arange方法用增量法创建向量。该方法返回一个ndarray对象,包含给定范围内的等间隔值。语法格式为:
numpy.arange(start, stop, step, dtype)
其中,start表示范围的起始值,默认为0;stop表示范围的终止值(不包含);step表示两个值的间隔,默认值为1;dtype表示返回的ndarray对象的数据类型,如果没有提供,则会使用输入数据的数据类型。
下面的例子展示如何使用该函数:
>>> x=np.arange(5)
>>> print(x)
[0 1 2 3 4]
下面用dtype参数设置数据的数据类型。
>>> x = np.arange(5, dtype = float)
>>> print(x)
[0. 1. 2. 3. 4.]
当起始值大于终止值,并且步长值为负数时生成逆序排列的数据序列。
>>> x = np.arange(10,0,-2)
>>> print(x)
[10 8 6 4 2]
使用linspace函数和logspace函数,可以创建等差数列和等比数列。
linspace函数类似于arange函数,但是它指定范围之间的均匀间隔数,而不是步长。 该函数的语法格式为:
numpy.linspace(start, stop, num, endpoint, retstep, dtype)
其中,start表示序列的起始值;stop表示序列的终止值,如果endpoint为true,该值包含于序列中;num为要生成的等间隔数,默认值为50;endpoint表示序列中是否包含stop值,默认值为ture,此时间隔步长取为(stop-start)/(num-1) ,否则间隔步长取为(stop-start)/num;retstep的值如果为true时,输出数据序列和连续数字之间的步长值;dtype表示输出ndarray的数据类型。
下面的例子展示了linspace函数的用法。
>>> x=np.linspace(10,20,5)
>>> print(x)
[10. 12.5 15. 17.5 20.]
将endpoint参数的值设置为False,此时步长值为(20-10)/5=2。序列不包含终止值。
>>> x=np.linspace(10,20, 5, endpoint = False)
>>> print(x)
[10. 12. 14. 16. 18.]
使用logspace函数,可以生成等比数列。它返回一个ndarray对象,其中包含在对数刻度上均匀分布的数字。 刻度的起始值和终止值是某个底数的幂,通常为 10。
numpy.logscale(start, stop, num, endpoint, base, dtype)
其中,start表示起始值是base ** start;stop表示终止值是base ** stop;num表示范围内的取值个数,默认值为50;endpoint为true时,终止值包含在输出数组当中;base表示对数空间的底数,默认值为10;dtype表示输出数据的数据类型,如果没有提供,则取决于其它参数。
下面的例子展示了logspace函数的用法。
# 默认时以10为底
>>> x = np.logspace(1.0, 2.0, num = 10)
>>> print(x)
[ 10. 12.91549665 16.68100537 21.5443469 27.82559402
35.93813664 46.41588834 59.94842503 77.42636827 100. ]
# 将对数空间的底数设置为 2
>>> x = np.logspace(1,10,num = 10, base = 2)
>>> print(x)
[ 2. 4. 8. 16. 32. 64. 128. 256. 512. 1024.]
使用fromiter函数,可以通过迭代的方法从任何可迭代对象构建一个ndarray对象,返回一个新的一维数组。该函数的语法格式为:
numpy.fromiter(iterable, dtype, count = -1)
其中,iterable表示任何可迭代对象;dtype表示返回数据的数据类型;count表示需要读取的数据个数,默认为-1,读取所有数据。
下面的例子从给定列表获得迭代器,然后使用该迭代器创建向量。
>>> lst = range(5)
>>> it = iter(lst)
>>> x = np.fromiter(it, dtype = float)
>>> print(x)
[0. 1. 2. 3. 4.]
通过列表嵌套的方法,可以直接创建二维和多维数组。例如,下面创建一个2*2的矩阵。
>>> c=np.array([[1.,2.],[3.,4.]])
>>> print(c)
[[1. 2.]
[3. 4.]]
NumPy数组的索引和切片
通过索引或切片,可以从NumPy数组中获取单个的值或者连续获取多个值。下面用arange方法创建一个NumPy数组。
>>> a=np.arange(8)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7])
获取数组中的第3个值。注意索引号的基数为0。
>>> a[2]
2
获取数组中第3-5范围内的值。注意包头不包尾原则,即索引号5对应的第6个值不包括进来。
>>> a[2:5]
array([2, 3, 4])
获取数组中第3个及后面所有的值。注意冒号的用法,冒号表示连续取值,即进行切片操作。冒号在前面,表示前面的值全取;冒号在后面,表示后面的值全取;冒号在两个数之间,表示取这两个数确定的范围内的所有值。
>>> a[2:]
array([2, 3, 4, 5, 6, 7])
获取数组中前5个数据。
>>> a[:5]
array([0, 1, 2, 3, 4])
获取数组中倒数第3个值。
>>> a[-3]
5
获取数组中倒数第3个及它后面所有的值。
>>> a[-3:]
array([5, 6, 7])
NumPy数组计算
作为Python科学计算的基础包,NumPy封装了大量基础数学、统计分析、线性代数和数值分析等相关的函数。使用这些函数,可以很方便地进行计算,也可以利用它们进行二次开发。
一、数学函数
NumPy提供的基础数学函数如表7-3所示,包括求绝对值的函数、求平方、平方根、指数、对数、圆整和三角函数等。
表7-3 NumPy包提供的数学函数
| 函 数 | 说 明 |
|---|---|
| abs, fabs | 绝对值。对于非复数,用fabs函数更快 |
| square | 元素取平方 |
| sqrt | 元素取平方根 |
| exp | 元素的指数 |
| log, log10, log2 | 元素的自然对数、10为底的对数、2为底的对数 |
| sign | 计算元素的正负号,1为正数,0为零,-1为负数 |
| cell | 元素取大于等于该值的最小整数 |
| floor | 元素取小于等于该值的最大整数 |
| rint | 元素取原值四舍五入的整数 |
| cos, cosh, sin, sinh, tan, tanh | 三角函数 |
| arccos, arccosh, arcsin, arcsinh, arctan, arctanh | 反三角函数 |
下面导入NumPy包,对于给定的列表,计算列表元素的平方值和正弦值。
>>> import numpy as np
>>> a=[3,2,5,1,4]
>>> np.square(a) #平方
array([ 9, 4, 25, 1, 16], dtype=int32)
>>> np.sin(a) #正弦
array([ 0.14112001, 0.90929743, -0.95892427, 0.84147098, -0.7568025 ])
二、统计计算
NumPy包提供的统计分析函数如表7-4所示,包括求最大值、最小值、均值、中值、和、方差等统计量的函数。
表7-4 NumPy包提供的统计函数
| 函 数 | 说 明 |
|---|---|
| min | 最小值 |
| max | 最大值 |
| mean | 均值 |
| median | 中值 |
| sum | 和 |
| prod | 乘积 |
| cumsum | 累加求和 |
| cumprod | 累加求积 |
| std | 标准差 |
| var | 方差 |
| argmin | 最小值的索引 |
| argmax | 最大值的索引 |
下面导入NumPy包,对于给定的列表数据,计算指定的统计量。
>>> import numpy as np
>>> a=[3,2,5,1,4]
>>> np.max(a) #最大值
5
>>> np.mean(a) #均值
3.0
>>> np.sum(a) #和
15
>>> np.median(a) #中值
3.0
>>> np.var(a) #方差
2.0
三、构造特殊矩阵
矩阵计算中常常需要构造一些特殊矩阵,比如元素全为0的矩阵、元素全为1的矩阵、单位矩阵等。表7-5列出了NumPy包提供的构造特殊矩阵的函数。
表7-5 NumPy包提供的构造特殊矩阵的函数
| 函 数 | 说 明 |
|---|---|
| numpy.zeros | 创建一个元素全部为0的矩阵 |
| numpy.ones | 创建一个元素全部为1的矩阵 |
| numpy.eye | 创建一个对角线元素为1,其余元素为0的矩阵 |
| numpy.identity | 创建一个指定大小的单位矩阵 |
| numpy.random.randn | 创建一个指定大小的矩阵,元素为随机数 |
| numpy.empty | 创建一个新矩阵 |
下面导入NumPy包,用NumPy包提供的函数构造特殊矩阵。
>>> import numpy as np
>>> np.ones((3,2)) #3行2列的矩阵,值全为1
array([[1., 1.],
[1., 1.],
[1., 1.]])
>>> np.zeros((2,4)) #2行4列的矩阵,值全为0
array([[0., 0., 0., 0.],
[0., 0., 0., 0.]])
>>> np.random.randn(2,3) #2行3列的矩阵,值全为随机数
array([[ 0.76904717, -0.33417294, 0.89698686],
[-1.88668519, 0.057794 , 0.60373711]])
四、表达式运算
可以对NumPy数组进行算术运算、比较运算和逻辑运算等,NumPy包提供的表达式运算函数如表7-6中所示。
表7-6 NumPy包提供的数组表达式运算函数
| 函 数 | 说 明 |
|---|---|
| add | 数组对应的元素相加 |
| subtract | 数组对应的元素相减 |
| multiply | 数组对应的元素相乘 |
| divide, floor_divide | 数组对应的元素相除或相除后向下圆整 |
| power | 第1个数组的元素用第2个数组的对应元素进行指数运算 |
| maximum, fmax | 元素的最大值,fmax函数忽略空值 |
| minimum, fmin | 元素的最小值,fmin函数忽略空值 |
| mod | 元素求模运算 |
| copysign | 第2个数组中元素的符号复制给第1个数组中的元素 |
| greater, greater_equal, less, less_equal, equal, not_equal | 比较运算,大于、大于等于、小于、小于等于、等于、不等于,相当于>, >=, <, <=, ==, != |
| logical_and, logical_or, logical_xor | 逻辑运算,逻辑与、逻辑或、逻辑异或,相当于&, |, ^ |
下面导入NumPy包,用NumPy包提供的函数对给定数组进行四则运算和比较运算。
>>> import numpy as np
>>> a=np.array([[1,2,3],[4,5,6]])
>>> b=np.array([[5,8,2],[4,9,3]])
>>> np.add(a,b) #元素求和
array([[ 6, 10, 5],
[ 8, 14, 9]])
>>> np.multiply(a,b) #元素相乘
array([[ 5, 16, 6],
[16, 45, 18]])
>>> np.greater(a,b) #元素比较
array([[False, False, True],
[False, False, True]])
五、线性代数
NumPy包提供了一些线性代数计算的函数如表7-7所示,包括矩阵转置、相乘、行列式、求逆和解方程等。
表7-7 NumPy包提供的线性代数计算函数
| 函 数 | 说 明 |
|---|---|
| numpy.transpose | 转置 |
| numpy.dot | 点积,数组对应元素相乘 |
| numpy.vdot | 两个向量的点积 |
| numpy.inner | 内积 |
| numpy.matmul | 矩阵相乘 |
| numpy.linalg.det | 行列式 |
| numpy.linalg.solve | 解线性方程 |
| numpy.linalg.inv | 矩阵求逆 |
下面导入NumPy包,用NumPy包提供的函数进行线性代数运算。
>>> import numpy as np
>>> a=[[1,2,3],[4,5,6],[7,8,9]]
>>> np.transpose(a) #矩阵转置
array([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
>>> np.linalg.det(a) #矩阵行列式
6.66133814775094e-16
>>> np.linalg.inv(a) #矩阵求逆
array([[-4.50359963e+15, 9.00719925e+15, -4.50359963e+15],
[ 9.00719925e+15, -1.80143985e+16, 9.00719925e+15],
[-4.50359963e+15, 9.00719925e+15, -4.50359963e+15]])
Excel工作表与NumPy数组交换数据
使用Python的xlwings包可以很方便地实现NumPy数组数据在Excel工作表中的读写。下面将一个二维NumPy数组写入到Excel工作表中B2单元格为左上角的区域。
>>> import numpy as np
>>> sht=xw.Book().sheets(1)
>>> sht.range('B2').value=np.array([[1,2,3],[4,5,6],[7,8,9]])
写入效果如图7-12所示。
图7-12 在Excel工作表中写入NumPy数据
将工作表中指定区域内的数据读取到NumPy数组中,用选项工具指定np.array值即可。下面将B2单元格所在区域内的数据读取到arr数组中。
>>> arr=sht.range('B2').options(np.array, expand='table').value
>>> arr
array([[1., 2., 3.],
[4., 5., 6.],
[7., 7., 9.]])