这里先学习NumPy库,它是Python科学计算库中的基础库,许多其他著名的科学计算库(如Pandas、Scikit-Learn等)都要用到NumPy库的一些功能。
NumPy是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表结构(Nested List Structure)要高效得多(该结构也可以用来表示矩阵),支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
一个用Python实现的科学计算包括:① 一个强大的N维数组对象Array;② 比较成熟的(广播)函数库;③ 用于整合C/C++和Fortran代码的工具包;④ 实用的线性代数、傅里叶变换和随机数生成函数。NumPy和稀疏矩阵运算包SciPy配合使用更加方便。
NumPy提供了许多高级的数值编程工具,如矩阵数据类型、矢量处理以及精密的运算库,专为进行严格的数字处理而产生,多为大型金融公司,以及核心的科学计算组织使用,如Lawrence Livermore、NASA,用其处理一些本来使用C++、Fortran或MATLAB等所做的任务。
NumPy的前身为Numeric,最早由Jim Hugunin与其他协作者共同开发。2005年,Travis Oliphant在Numeric中结合了另一个同性质的程序库Numarray的特色,并加入了其他扩展而开发了NumPy。NumPy开放源代码,并且由许多协作者共同维护开发。
NumPy是基于Python的,因此在安装NumPy之前,需要先安装Python。目前建议安装Anaconda,Anaconda是一个用于科学计算的Python工具,支持Linux、macOS、Windows系统,它包含众多流行的用于科学计算、数据分析的Python包。如果已经安装了Anaconda,那么NumPy就已经安装成功了。
Python NumPy在Windows、各种Linux发布版以及macOS上均有二进制安装包。在各个系统境下,安装NumPy的命令都是pip install numpy。下面简要介绍一些NumPy的基本操作,方便读者后续对机器学习方法的学习。
NumPy是一个Python库,部分用Python编写,但是大多数需要快速计算的部分都是用C或C++编写的。
如果已经在系统上安装了Python和pip,那么安装NumPy非常容易。请使用以下这条命令安装它:
pip install numpy
安装NumPy后,通过添加import关键字将其导入用户的应用程序:
import numpy
NumPy通常以np别名导入。在Python中,别名是用于引用同一事物的替代名称。请在导入时使用as关键字创建别名:
import numpy as np
现在,可以将NumPy包称为np而不是numpy。
版本字符串存储在__version__属性中。
【例3-1】 检查NumPy版本。
输入如下代码:
import numpy as np
print(np.__version__)
运行结果如下:
1.21.5
NumPy最重要的一个特点是其 N 维数组对象ndarray,它是一系列同类型数据的集合,以0下标为开始进行集合中元素的索引。
ndarray对象是用于存放同类型元素的多维数组。ndarray中的每个元素在内存中都有相同存储大小的区域。ndarray内部由以下内容组成:
(1)一个指向数据(内存或内存映射文件中的一块数据)的指针。
(2)数据类型或dtype,描述在数组中的固定大小值的格子。
(3)一个表示数组形状(shape)的元组,表示各维度大小的元组。
(4)一个跨度(stride)元组,其中的整数指的是为了前进到当前维度下一个元素需要“跨过”的字节数。跨度可以是负数,这样会使数组在内存中后向移动,切片中的obj[::-1]或obj[:,::-1]就是如此。
创建一个ndarray只需调用NumPy的array函数即可:
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin
= 0)
其中参数说明如表3-1所示。
表3-1 numpy.array参数说明
【例3-2】 numpy.array应用举例。
输入如下代码:
运行结果如下:
ndarray对象由计算机内存的连续一维部分组成,并结合索引模式,将每个元素映射到内存块中的一个位置。内存块以行顺序(C样式)或列顺序(FORTRAN或MATLAB风格,即前述的F样式)来保存元素。
NumPy支持的数据类型比Python内置的类型要多很多,基本上可以和C语言的数据类型对应上,其中部分类型对应Python内置的类型。表3-2列举了NumPy的基本数据类型。
表3-2 NumPy的基本数据类型
NumPy的数值类型实际上是dtype对象的实例,并对应唯一的字符,包括np.bool_、np.int32、np.float32等。
数据类型对象(numpy.dtype类的实例)用来描述与数组对应的内存区域是如何使用的,它描述了数据的以下几个方面:
(1)数据的类型(整数、浮点数或者Python对象)。
(2)数据的大小(例如,整数使用多少字节存储)。
(3)数据的字节顺序(小端法或大端法)。
(4)对于结构化类型,描述字段的名称、每个字段的数据类型和每个字段所取的内存块的部分。
(5)如果数据类型是子数组,则描述其形状和数据类型。
dtype对象是使用以下语法构造的:
numpy.dtype(object, align, copy)
参数说明如下:
object:要转换为的数据类型对象。
align:如果为true,则填充字段使其类似C语言的结构体。
copy:复制dtype对象,如果为false,则是对内置数据类型对象的引用。
【例3-3】 NumPy数据类型应用举例。
输入如下代码:
运行结果如下:
每个内置类型都有一个唯一定义它的字符代码,如表3-3所示。
表3-3 内置类型标识符
ndarray数组除了可以使用底层ndarray构造器来创建外,也可以通过以下几种方式来创建。
numpy.empty方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组:
numpy.empty(shape, dtype = float, order = 'C')
参数说明如下:
shape:数组形状。
dtype:数据类型,可选。
order:有C和F两个选项,分别代表行优先和列优先,是计算机内存中存储元素的顺序。
【例3-4】 numpy.empty创建空数组。
输入如下代码:
import numpy as np
s = np.empty([4, 6], dtype = int)
print(s)
运行结果如下:
数组元素为随机值,因为它们未初始化。
创建指定大小的数组,数组元素以0来填充:
numpy.zeros(shape, dtype = float, order = 'C')
参数说明如下:
shape:数组形状。
dtype:数据类型,可选。
order:C用于C语言的行数组,或者F用于FORTRAN的列数组。
【例3-5】 numpy.zeros应用举例说明。
输入如下代码:
运行结果如下:
[0. 0. 0. 0. 0.]
[0 0 0 0 0]
[[(0, 0) (0, 0)]
[(0, 0) (0, 0)]]
创建指定形状的数组,数组元素以1来填充:
numpy.ones(shape, dtype = None, order = 'C')
参数说明如下:
shape:数组形状。
dtype:数据类型,可选。
order:C用于C语言的行数组,或者F用于FORTRAN语言的列数组。
【例3-6】 numpy.ones应用举例说明。
输入如下代码:
import numpy as np
# 默认为浮点数
x = np.ones(5)
print(x)
print('*'*10)
# 自定义类型
x = np.ones([3, 3], dtype=int)
print(x)
运行结果如下:
[1. 1. 1. 1. 1.]
**********
[[1 1 1]
[1 1 1]
[1 1 1]]
还可以从已有数组创建数组。
1)numpy.asarray
numpy.asarray类似于numpy.array,但numpy.asarray的参数只有3个,比numpy.array少两个。
numpy.asarray(a, dtype = None, order = None)
参数说明如下:
a:任意形式的输入参数,可以是列表、列表的元组、元组、元组的元组、元组的列表、多维数组。
dtype:数据类型,可选。
order:可选,有C和F两个选项,分别代表行优先和列优先,是计算机内存中存储元素的顺序。
【例3-7】 将列表转换为ndarray。
输入如下代码:
import numpy as np
x = [4, 5, 6, 10000]
a = np.asarray(x)
print(a)
运行结果如下:
[ 4 5 6 10000]
【例3-8】 将元组转换为ndarray。
输入如下代码:
import numpy as np
x = (100, 2000, 300000)
a = np.asarray(x)
print(a)
运行结果如下:
[ 100 2000 300000]
【例3-9】 元组列表转换为ndarray。
输入如下代码:
运行结果如下:
[(1, 2, 3) (4, 5)]
**********
[1. 2. 3.]
2)numpy.frombuffer
numpy.frombuffer用于实现动态数组。
numpy.frombuffer接收buffer输入的参数,以流的形式读入转化成ndarray对象。
buffer是字符串的时候,Python 3默认str是Unicode类型,所以要转成bytestring需在原str前加上b。
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
参数说明如下:
buffer:可以是任意对象,会以流的形式读入。
dtype:返回数组的数据类型,可选。
count:读取的数据数量,默认为-1,读取所有数据。
offset:读取的起始位置,默认为0。
【例3-10】 numpy.frombuffer应用实例。
输入如下代码:
import numpy as np
s = b'Hello World'
a = np.frombuffer(s, dtype='S1')
print(a)
运行结果如下:
[b'H' b'e' b'l' b'l' b'o' b' ' b'W' b'o' b'r' b'l' b'd']
3)numpy.fromiter
numpy.fromiter方法从可迭代对象中建立ndarray对象,返回一维数组。
numpy.fromiter(iterable, dtype, count=-1)
参数说明如下:
iterable:可迭代对象。
dtype:返回数组的数据类型。
count:读取的数据数量,默认为-1,读取所有数据。
【例3-11】 numpy. fromiter应用实例。
输入如下代码:
import numpy as np
# 使用 range 函数创建列表对象
List = range(10)
it = iter(List)
# 使用迭代器创建 ndarray
x = np.fromiter(it, dtype=float)
print(x)
运行结果如下:
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
NumPy包含大量数学运算函数,包括三角函数、算术函数、舍入函数等。
1)加、减、乘、除函数
NumPy的算术函数又包含简单的加、减、乘、除等。参与运算的数组必须具有相同的形状或符合数组广播规则。
【例3-12】 NumPy加、减、乘、除应用举例。
输入如下代码:
运行结果如下:
2)numpy.reciprocal()函数
numpy.reciprocal()函数返回参数逐元素的倒数。
【例3-13】 numpy.reciprocal()函数应用举例。
输入如下代码:
import numpy as np
s = np.array([888, 1000, 20,
0.1]) print('原数组是:')
print(s)
print('*'*20)
print('调用reciprocal函数:')
print(np.reciprocal(s))
运行结果如下:
原数组是:
[8.88e+02 1.00e+03 2.00e+01 1.00e-01]
********************
调用reciprocal函数:
[1.12612613e-03 1.00000000e-03 5.00000000e-02 1.00000000e+01]
3)numpy.power()函数
numpy.power()函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中的相应元素的幂。
【例3-14】 numpy.power()函数应用举例。
输入如下代码:
运行结果如下:
4)numpy.mod()函数
numpy.mod()函数计算输入数组中的相应元素相除后的余数。此外,numpy.remainder()函数也产生相同的结果。
【例3-15】 numpy.mod()函数应用举例。
输入如下代码:
运行结果如下:
1)sin()、cos()和tan()函数
NumPy提供了标准的三角函数:sin()、cos()、tan()。
【例3-16】 NumPy三角函数应用举例。
输入如下代码:
运行结果如下:
2)arcsin()、arccos()和arctan()函数
arcsin()、arccos()和arctan()函数返回给定角度的sin()、cos()和tan()的反三角函数。这些函数的结果可以通过numpy.degrees()函数将弧度转换为角度。
【例3-17】 arcsin()、arccos()和arctan()函数应用举例。
输入如下代码:
运行结果如下:
1)numpy.around()函数
numpy.around()函数返回指定数字的四舍五入值。
numpy.around(a,decimals)
参数说明如下:
a:数组。
decimals:舍入的小数位数,默认值为0,如果为负,则整数将四舍五入到小数点左侧的位置。
【例3-18】 numpy.around()函数应用举例。
输入如下代码:
运行结果如下:
原数组:
[100. 100.5 123. 0.876 76.998]
********************
舍入后:
[100. 100. 123. 1. 77.] [100. 100.5 123. 0.9 77. ] [100. 100. 120. 0. 80.]
2)numpy.floor()函数
numpy.floor()函数返回小于或者等于指定表达式的最大整数,即向下取整。
【例3-19】 numpy.floor()函数应用举例。
输入如下代码:
import numpy as np
s = np.array([-9999.7, 100333.5, -23340.2, 0.987, 10.88888])
print('提供的数组:')
print(s)
print('*'*20)
print('修改后的数组:')
print(np.floor(s))
运行结果如下:
3)numpy.ceil()函数
numpy.ceil()函数返回大于或者等于指定表达式的最小整数,即向上取整。
【例3-20】 numpy.ceil()函数应用举例。
输入如下代码:
运行结果如下: