目录
一、什么是Numpy?
NumPy是Python中科学计算的基础包。它是一个Python库,提供多维数组对象,派生对象以及用于数组快速操作的各种API,包括数学、逻辑、形状操作、排序、选择、输入输出、基本线性代数,基本统计运算和随机模拟等等。
NumPy的核心是 ndarray(n-dimensional array) 对象,即 n 维数组,它与Python列表的区别如下:
- NumPy数组在创建时具有固定的大小,而Python的列表可以动态增长。更改ndarray的大小将创建一个新数组并删除原来的数组。
- NumPy数组中的元素都需要具有相同的数据类型,而Python的列表可以拥有不同数据类型的元素。
- NumPy数组有助于对大量数据进行高级数学和其他类型的操作,通常这些操作的执行效率更高,比使用Python列表的代码更少。
- 越来越多基于Python的科学/数学软件包使用NumPy数组,虽然这些工具通常都支持Python的列表作为参数,但它们在处理之前会还是会将输入的列表转换为NumPy的数组,而且也通常输出为NumPy数组。
二、安装Numpy
在命令行中使用如下命令进行安装:
pip install numpy
对于conda用户,则可用
conda install numpy
安装完后,我们就可以导入Numpy了,我们一般使用如下代码进行导入:
import numpy as np
np
是 numpy
的简写,目的是为了后面编写程序时能够更加简洁方便,同时使用 np
不会失去可读性,并且这种简写方式也是绝大多数人的选择。
三、ndarray 和 matrix 该使用哪一个?
我们已经知道,ndarray 是Numpy中的 n 维数组对象,但除此之外,Numpy还提供了一种特殊的矩阵类型:matrix,它是 ndarray 的子类。
ndarray 和 matrix 都可以完成对矩阵的运算,那么哪一个更好呢?
先说答案:使用 ndarray。
原因有以下几点:
- ndarray 是Numpy中标准的向量/矩阵/张量类型,许多Numpy函数返回的是数组,而不是矩阵。
- 使用 ndarray 比使用 matrix 构建矩阵更为方便。
- ndarray 可以处理高维数组,而 matrix 只能处理二维数组。
- 在 ndarray 中,运算符
*
表示按元素相乘(也可以用multiply()),运算符@
表示矩阵乘法(也可以用dot());而在 matrix 中,*
代表的是矩阵乘法,按元素相乘则需要使用multiply()。
四、创建 n 维数组
想必你已经对Numpy中的 n 维数组对象 ndarray 有了一个大概的了解,那么我们该如何创建 n 维数组呢?
有以下两种常用方法:
- 将现有的Python列表、元组转换为 ndarray
- 使用Numpy自带的数组创建函数(如arange、linspace等)
4.1 将现有的列表、元组转换为 n 维数组
方法很简单,只需要外面套一个 np.array() 即可。
对于列表:
A = np.array([1, 2, 3])
print(A)
print(type(A))
# [1 2 3]
# <class 'numpy.ndarray'>
对于元组:
A = np.array((1, 2, 3))
print(A)
print(type(A))
# [1 2 3]
# <class 'numpy.ndarray'>
4.2 使用Numpy自带的数组创建函数
我们这里只做一个简短的介绍,关于数组的创建、修改等内容详情见本系列的下一篇文章。
函数 | 描述 |
---|---|
np.arange([start], stop, [step]) | 创建一个在[start, stop)区间内的,步长为step的数组;start省略时默认为0,step省略时默认为1 |
np.linspace(start, stop, num) | 创建一个在[start, stop]区间内的,大小为num的数组 |
例如,若要创建 [ 0 , 10 ] [0, 10] [0,10] 中所有偶数的数组,我们可以使用arange函数,只需设置步长为 2:
A = np.arange(0, 11, 2)
print(A)
# [ 0 2 4 6 8 10]
也可以使用linspace函数,不过我们需要事先知道 [ 0 , 10 ] [0, 10] [0,10] 中的偶数有多少个:
A = np.linspace(0, 10, 6)
print(A)
# [ 0. 2. 4. 6. 8. 10.]
看起来arange和linspace返回的结果一样,但实际是不同的,具体这里就不再赘述了,详情可见下一篇文章。
4.3 对 ndarray 进行索引和切片
当然,我们可以像对待Python列表那样,对Numpy中的n维数组进行索引和切片:
A = np.arange(10)
print(A[3])
print(A[1:])
print(A[:-2])
print(A[::-1])
print(A[::2])
# 3
# [1 2 3 4 5 6 7 8 9]
# [0 1 2 3 4 5 6 7]
# [9 8 7 6 5 4 3 2 1 0]
# [0 2 4 6 8]
五、Numpy中的常量
常量 | 描述 |
---|---|
np.inf | 代表 + ∞ +\infty +∞ |
np.NINF | 代表 − ∞ -\infty −∞ |
np.nan | 代表非数字 |
np.e | 代表自然底数 |
np.pi | 代表 π \pi π |
np.euler_gamma | 代表欧拉常数 |
np.newaxis | 代表None |
注意: 以上提到的7个常量中,前六个都是浮点型,即 <class 'float'>
,只有最后一个是Nonetype型:<class 'NoneType'>
。
前六个常量想必大家都不陌生,并且在实际的编程任务中会经常用到。对于第七个常量:np.newaxis,我们会在后面的文章中进行详细讲解。
六、Numpy中的数据类型
Numpy支持比Python更多种类的数据类型,本节将介绍常见的数据类型,以及如何修改n维数组的数据类型。
6.1 布尔型
名称 | 描述 |
---|---|
np.bool8(np.bool_) | 布尔型数据类型(True 或者 False) |
6.2 整型
名称 | 描述 |
---|---|
np.int8 | 字节(-128 to 127) |
np.int16 | 整数(-32768 to 32767) |
np.int32 | 整数(-2147483648 to 2147483647) |
np.int64(np.int_) | 整数(-9223372036854775808 to 9223372036854775807) |
np.uint8 | 无符号整数(0 to 255) |
np.uint16 | 无符号整数(0 to 65535) |
np.uint32 | 无符号整数(0 to 4294967295) |
np.uint64 | 无符号整数(0 to 18446744073709551615) |
6.3 浮点型
名称 | 描述 |
---|---|
np.float16 | 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位 |
np.float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位 |
np.float64(np.float_) | 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位 |
6.4 复数型
名称 | 描述 |
---|---|
np.complex64 | 复数,由两个32位浮点数(实数和虚数部分)组成 |
np.complex128(np.complex_) | 复数,由两个64位浮点数(实数和虚数部分)组成 |
6.5 dtype
6.5.1 查看数据类型
dtype可以用来查看ndarray中元素的数据类型。我们先做一些实验:
实验一
A = np.array([1, 1])
print(A.dtype)
# int32
可见对于n维整型数组,Numpy默认的数据类型是 int32
。
实验二
A = np.array([1., 1.])
print(A.dtype)
# float64
可见对于n维浮点型数组,Numpy默认的数据类型是 float_
。
实验三
A = np.array([1j, 1j])
print(A.dtype)
# complex128
可见对于n维复数型数组,Numpy默认的数据类型是 complex_
。
6.5.2 设置数组的数据类型
若要设置数组的数据类型,我们可以这样做:
A = np.array([1, 2, 3], dtype=np.float64)
print(A)
# [1. 2. 3.]
可以发现整型数组已经转化为了浮点型数组。
当然我们还有更简便的方法:
A = np.float64([1, 2, 3])
print(A)
# [1. 2. 3.]
以上提到的两种方法都是在创建数组的同时设置数据类型,我们还可以使用astype()方法对已有的数组更改数据类型:
A = np.array([1, 2, 3])
print(A.dtype)
A = A.astype(np.float64)
print(A.dtype)
# int32
# float64
6.5.3 溢出问题
如果数据类型设置不当,可能会造成数据溢出。例如,在创建下面这样的数组时:
A = np.array([3333443333, 4444334444], dtype=np.int32)
会报错: OverflowError
,这是因为数组中有元素的值大于 int32
的范围了,我们需要使用 int64
才能继续创建。
A = np.array([3333443333, 4444334444], dtype=np.int64)
print(A)
# [3333443333 4444334444]