引言
NumPy功法宝典主要分为三部分:
- 简要介绍NumPy模块的功能和安装;
- 介绍NumPy的必备语法;
- 将NumPy所有函数分类,以便能够根据需求快速定位到相关函数的用法。
声明
NumPy需要Python编程基础,没有掌握Python语法,千万不要强行修炼,恐心神受创。
第一部分
简介
NumPy是一个Python科学计算的基础包,包含了多维数组对象(multidemensional array object)和诸如矩阵等多种衍生对象,然后基于此进行数学计算、逻辑计算、维度改变、排序、筛选、输入输出、离散傅里叶变换、基础线性代数、基础统计操作、随机模拟等等一系列操作。
NumPy的核心就是一个ndarray对象,封装了包含相同类型数据的n维数组。
NumPy和Python内置序列的不同:
- NumPy中的数组在创建的时候长度是固定的,修改长度会新建数组、删除原有数组;
- NumPy数组中的元素必须属于同一类型,对象数组除外;
- NumPy数组帮助实现大量数据的高级数学计算和其他类型操作,并且执行的效率比Python内置序列要更高;
- 越来越多的Python包都开始基于NumPy并且处理数据时都直接返回NumPy数组,所以掌握NumPy是非常有必要的
安装
安装NumPy非常简单,使用pip安装即可。本宝典围绕NumPy 1.15.4展开,并且每年会保持更新。
第二部分
核心数据结构——ndarray
NumPy的核心数据结构是一个包含同类型数据的多维数组ndarray,因为维度可能较高,所以常常使用一个包含正整数的元组进行索引,NumPy中维度又称“轴”(axis,复数是axes)
More Details
举个例子,[1, 2, 1]这个多维数组有一个轴,而[[1, 2], [2, 3], [3, 4]]就有两个轴,第一个轴对应行,长度为3,第二个轴对应列,长度为2*
下表介绍了多维数组ndarray的属性:
属性 | 解释 |
---|---|
ndarray.ndim | 返回ndarray的轴数 |
ndarray.shape | 以元组的形式返回ndarray的维度 |
ndarray.size | 返回ndarraty中元素的总数,相当于ndarray.shape中各个数字的乘积 |
ndarray.dtype | 返回ndarray中元素的类型,常见的有numpy.int32, numpy.float32, numpy.float64 |
ndarray.itemsize | 返回ndarray中元素所占的字节数 |
ndarray.data | 不建议使用 |
创建ndarray
创建的方法有以下五种:
- 直接将Python的列表或者元组(二者嵌套也可以)转换为多维数组;(适用于中小型数据的人工构建)
- 使用NumPy初始化函数,通过占位符内容来初始化ndarray。(偏向大型数据的自动构建)
- 从磁盘、标准格式、自定义格式中读取ndarray (**待补充**)
- 从字符串或缓存中创建 (**待补充**)
- 使用特殊的库函数,比如random (**待补充**)
在创建的时候,可以显式地指定dtype,如果不指定,NumPy会自动指定。
创建示例下表介绍了NumPy常用的初始化函数,使用时只需要指定维度即可快速构建多维数组:
函数 | 解释 |
---|---|
zeros(shape)/zeros_like() | 构建全0数组 |
ones(shape)/ones_like() | 构建全1数组 |
empty(shape)/empty_like() | 构建随机数组 |
arange(a, b, c) | 类似Python中range()的构建方法,a,b,c分别代表起始值、终止值、步长/方向 |
linspace(a, b, c) | 同上,只不过c不代表步长,而代表在a与b之间生成数字的个数 |
random.random(shape) | 创建指定维度的随机数组,元素为0到1之间 |
random.rand() | (**待补充**) |
random.randn() | (**待补充**) |
fromfunction() | (**待补充**) |
fromfile() | (**待补充**) |
NumPy在显示较大的多维数组的时候,为了美观只显示了头部和尾部,可以通过np.set_printoptions(threshold=np.nan)改为全显示
元素级的算数运算
使用算数运算符对多维数组进行算数运算时,执行的是两个多维数组相同位置上元素之间的算数运算。另外,还有一些统计函数也是元素级的(部分numpy全局函数,会加上"np."前缀)
函数 | 解释 |
---|---|
max(axis)/min(axis) | 统计最值 |
sum(axis) | 求和 |
np.exp(ndarray) | 计算自然指数 |
np.sqrt(ndarray) | 计算平方根 |
np.add(ndarray1, ndarray2) | 元素级数组相加,相当于ndarray1+ndarray2 |
np.floor(ndarray) | 计算小于的最大整数 |
np.ceil(ndarray) | 计算大于的最小整数 |
如果真正实现多维数组之间的矩阵相乘,可以使用@或者dot
索引、切片和迭代
单个维度ndarray的索引、切片和迭代和Python内置列表的操作一样。
多维ndarray则依次按轴索引和切片。
迭代可以使用flat属性,获取ndarray的迭代器
for element in ndarray.flat:
# to do something
更改多维数组的维度
函数名 | 解释 |
---|---|
ndarray.ravel() | 将多维数组压成一个一维数组,并返回 |
ndarray.reshape(shape) | 将ndarray调整为指定的维度并返回,reshape([3, 4])或者reshape(3, 4)都可以,如果是reshape(3, -1)则表示最后一个轴自动计算 |
ndarray.resize(shape) | 原地方法,和reshape稍有不同 |
ndarray.T | 矩阵的转置 |
ndarray[:, newaxis] | 加一个轴,需要导入from numpy import newaxis |
数组的连接
函数名 | 解释 |
---|---|
np.vstack((ndarray1, ndarray2)) | 竖直堆积,对于二维数组等价于row_stack() |
np.hstack((ndarray1, ndarray2)) | 水平堆积,对于二维数组等价于column_stack() |
np.c() | 沿着第二个轴将切片对象连接在一起 |
np.r() | 沿着第一个轴将切片对象连接在一起 |
import numpy as np
from numpy import newaxis
a = np.arange(4)
print('a的值为:')
print('0轴前加上新轴newaxis:')
print(a[newaxis, :])
print('末尾加上新轴newaxis:')
print(a[:, newaxis])
b = np.arange(8).reshape(2, 4)
print('b的值为:')
print(b)
print('堆积后:')
print(np.vstack((a[newaxis, :], b)))
综合例子
np.r_和np.c_的使用
二者使用较为复杂,np.r_[1:4, 0, 4]的输出结果:[1, 2, 3, 0, 4],这里的切片索引1:4就对应着1,2,3,然后拼接上后面的几个数字
待补充
数组的分割
分割和连接是相反的操作。
函数名 | 解释 |
---|---|
hsplit(ndarray, 3) | 将ndarray水平分割为三个大小相同的多维数组 |
hsplit(ndarray, (3, 4)) | 将ndarray水平分割为三个子数组,切割位置为第三列、第四列 |
vsplit() | 依次类推 |
复制与视图
复制分为深复制和浅复制两种,由于NumPy中的==运算符会产生布尔数组,所以常用is来区分二者。
NumPy中的深浅复制和其余语言不同,为了统一,在这里稍作修改:深复制得到的变量的值发生变化会引起原变量的值的变化,而浅复制则相反。
1. 赋值操作不是复制
执行了a = b
那么a is b
一定成立
2. view()和base
ndarray的切片其实就是创建一个视图,而视图其实生成了一个新的数组对象,只不过在产生的过程中视图窗口中的数据保持不变,需要注意的是修改视图中的数据等价于修改原数据(修改视图的维度和数据类型除外)。
a = np.array([1, 2, 3])
b = a.view()
print(a is b) # 输False,产生视图的过程会生成一个新的数组对象,数据和原来一模一样
b[0] = -1
print(b) # 输出[-1, 2, 3]
print(a) # 输出[-1, 2, 3]
base的属性可以从视图回到原数据。
a = np.array([1, 2, 3])
b = a.view()
b = b.base
print(a is b) # 输出True
3. copy()实现浅复制
copy()函数得到的是一个独立的数组对象副本,对此副本的所有操作,都将和原来数组无关。
a = np.array([1, 2, 3])
b = a.copy()
print(a is b) # 输出True
第三部分
操作类型 | 举例 |
---|---|
数组创建 | arange, array, copy, empty, empty_like, eye, fromfile, fromfunction, identity, linspace, logspace, mgrid, ogrid, ones, ones_like, r, zeros, zeros_like |
转换 | ndarray.astype, atleast_1d, atleast_2d, atleast_3d, mat |
操作 | array_split, column_stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, ndarray.item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack |
查询 | all, any, nonzero, where |
排序 | argmax, argmin, argsort, max, min, ptp, searchsorted, sort |
运算 | choose, compress, cumprod, cumsum, inner, ndarray.fill, imag, prod, put, putmask, real, sum |
基本统计 | cov, mean, std, var |
待补充
网友评论