Numpy 学习笔记
前言
NumPy 是 Python 中科学计算的基础包。它是一个 Python 库,提供多维数组对象,各种派生对象(如掩码数组和矩阵),以及用于数组快速操作的各种 API,有包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变换、基本线性代数,基本统计运算和随机模拟等等。
在学习 numpy 之前,你总得在 python 上装上 numpy 吧,安装命令非常简单:
代码语言:javascript复制pip install numpy
安装完成之后,只需要这样:
代码语言:javascript复制import numpy
当然更多人的选择是这样,简单一点总是友好的。
代码语言:javascript复制import numpy as np
一个例子
代码语言:javascript复制>>> import numpy as np
>>> a = np.arange(15).reshape(3,5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a.shape
(3, 5)
>>> a.dtype
dtype('int32')
>>> a.size
15
创建数组
NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。ndarray 对象是用于存放同类型元素的多维数组。ndarray 中的每个元素在内存中都有相同存储大小的区域。
最开始的命令当然是要学习如何创建一个数组,只有创建了一个数组之后,才能愉快的玩耍
代码语言:javascript复制# 1维数组
a = np.array([1, 2, 3, 4, 5]) # >>> [1, 2, 3, 4, 5]
b = np.array((1, 2, 3, 4, 5)) # >>> [1, 2, 3, 4, 5]
c = np.arange(1, 6) # >>> [1, 2, 3, 4, 5]
上面的代码显示了创建数组的几种不同方法,最基本的方法是将序列传递给 NumPy 的 array()函数。
注意,单纯传入一串数字是错误的
代码语言:javascript复制a = np.array([1, 2, 3, 4, 5]) # ✔
a = np.array(1, 2, 3, 4, 5) # ✖
类似的,你也可以通过传入多个序列或者嵌套,来构造二维数组以及多维数组
代码语言:javascript复制a = np.array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
a = np.arange(15).reshape(3,5)
很明显,手动输入一个有序的数组无疑是非常麻烦的,因此可以使用 arange()
和 reshape()
更快速的创建矩阵
另外,你也可以在创建时,指定 dtype
显式指定数组的类型:
a = np.array([1.5, 2, 3], [4.5, 5, 6], dtype = float)
NumPy 提供了几个函数来创建具有初始占位符内容的数组。
例如 zeros()
, ones()
, full()
, linspace()
, eye()
# 函数 zeros 创建一个由 0 组成的指定大小的数组, 注意括号
>>> np.zeros([2, 3])
array([[0., 0., 0.],
[0., 0., 0.]])
# 函数 ones 创建一个由 1 组成的指定大小的数组, 注意括号
>>> np.ones([2, 3])
array([[1., 1., 1.],
[1., 1., 1.]])
# 函数 full 创建一个全是指定元素的数组
>>> np.full((2, 3), 7)
array([[7, 7, 7],
[7, 7, 7]])
# 使用 linspace 函数来接收我们想要的元素数量的函数
# linspace(start, end, num)
>>> np.linspace(0, 2, 9)
array([0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])
# 使用 eye 创建主对角矩阵
>>> np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
# 使用 random 构建随机数组
>>> np.random.random((2,3))
array([[0.03258815, 0.15250532, 0.4428446 ],
[0.55359382, 0.3802597 , 0.67287016]])
数组属性
在最开始的例子中,我们使用了 shape
, size
, dtype
等的属性,通过其属性访问数组也显得非常方便快捷,下面是一些示例:
>>> a = np.arange(15).reshape(3,5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a.shape # 数组的维度
(3, 5)
>>> len(a) # 数组的长度
3
>>> a.ndim # 数组维数
2
>>> a.dtype # 数组元素的数据类型
dtype('int32')
>>> a.size # 数组中的元素数
15
>>> a.T # 数组转置
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])
基本操作
基本操作符
在创建了数组之后,我们就可以对数组进行操作,加减乘除等,你可以像平常使用
,-
,×
,÷
一样来进行数组计算。
>>> a = np.array([1, 2, 3, 4, 5])
>>> b = np.arange(10, 15)
>>> a b
>>> a - b
>>> a * b
>>> a / b
>>> a ** 2
>>> a > b
注意,上面的操作符都是对数组进行逐元素运算
如果你需要计算矩阵乘法,请使用 dot()
函数
>>> a.dot(b) # 矩阵乘法
特殊运算符
NumPy 还提供了一些别的用于处理数组的好用的运算符。
代码语言:javascript复制>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> a.sum() # 返回数组元素的总和
21
>>> a.sum(0) # 返回给定轴上的数组元素的总和
array([5, 7, 9])
>>> a.min() # 返回最小值
1
>>> a.argmax() # 返回最大值的索引
5
>>> a.mean(1) # 返回给定轴上的数组元素的平均值
array([2., 5.])
>>> a.cumsum() # 返回给定轴上元素的累积和
array([ 1, 3, 6, 10, 15, 21], dtype=int32)
切片和索引
ndarray 对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
对数组进行切片和索引就像列表或任何其他 Python 序列一样。如果你熟悉 Python,我想你并不会对他们感到陌生。
在对多维数组进行索引或切片时,通过对每个以逗号分隔的维度执行单独的切片,就像 Matlab 一样
代码语言:javascript复制>>> a = np.arange(15).reshape(3,5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a[2, 3] # 第 2 行,第 3 列
13
>>> a[0, 1:4] # 第 0 行,第 1 列到第 3 列
array([1, 2, 3])
>>> a[:2, 2:] # 前 2 行,后 3 列
array([[2, 3, 4],
[7, 8, 9]])
形状操作
改变数组的形状
我们可以使用 numpy 提供的各种命令更改数组的形状,其中 reshape
和 resize
较为常用,值得注意的是,reshape
产生一个新的数组,不改变原有数组的形状,而 resize
就地更改数组的形状和大小。
>>> a = np.floor(10*np.random.random((3,4)))
>>> a
array([[0., 5., 1., 4.],
[4., 5., 0., 2.],
[0., 5., 6., 2.]])
>>> a.reshape(6,2)
array([[0., 5.],
[1., 4.],
[4., 5.],
[0., 2.],
[0., 5.],
[6., 2.]])
>>> a.ravel()
array([0., 5., 1., 4., 4., 5., 0., 2., 0., 5., 6., 2.])
>>> a.resize(2,6)
>>> a
array([[0., 5., 1., 4., 4., 5.],
[0., 2., 0., 5., 6., 2.]])
下面是一些具体的说明
方法 | 描述 |
---|---|
reshape() | 返回包含具有新形状的相同数据的数组 |
resize() | 就地更改数组的形状和大小 |
ravel() | 返回一个扁平的数组 |
将不同数组堆叠在一起
我们可以使用 vstack
和 hstack
函数将几个数组进行垂直或者水平方向的拼接
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> b = np.arange(10, 16).reshape(2,3)
>>> np.vstack((a,b))
array([[ 1, 2, 3],
[ 4, 5, 6],
[10, 11, 12],
[13, 14, 15]])
>>> np.hstack((a,b))
array([[ 1, 2, 3, 10, 11, 12],
[ 4, 5, 6, 13, 14, 15]])
功能和方法概述
以下是按类别排序的一些有用的 NumPy 函数和方法名称的列表。有关完整列表,请参阅参考手册里的常用 API。
- 数组的创建(Array Creation) - arange, array, copy, empty, empty_like, eye, fromfile, fromfunction, identity, linspace, logspace, mgrid, ogrid, ones, ones_like, zeros, zeros_like
- 转换和变换(Conversions) - ndarray.astype, atleast_1d, atleast_2d, atleast_3d, mat
- 操纵术(Manipulations) - array_split, column_stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, ndarray.item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack
- 询问(Questions) - all, any, nonzero, where,
- 顺序(Ordering) - argmax, argmin, argsort, max, min, ptp, searchsorted, sort
- 操作(Operations) - choose, compress, cumprod, cumsum, inner, ndarray.fill, imag, prod, put, putmask, real, sum
- 基本统计(Basic Statistics) - cov, mean, std, var
- 基本线性代数(Basic Linear Algebra) - cross, dot, outer, linalg.svd, vdot
参考资料
- NumPy 中文