文章目录
1. NumPy起源
NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray ,它拥有一些额外的功能。 2005年,Travis Oliphant 通过将 Numarray 的功能集成到 Numeric 包中来创建 NumPy 包。 这个开源项目有很多贡献者。
2. NumPy 操作
- 数组的算数和逻辑运算。
- 傅立叶变换和用于图形操作的例程。
- 与线性代数有关的操作。 NumPy 拥有线性代数和随机数生成的内置函数。
3. NumPy - Ndarray 对象
NumPy 中定义的最重要的对象是称为 ndarray 的 N 维数组类型。 它描述相同类型的元素集合。 可以使用基于零的索引访问集合中的项目。ndarray中的每个元素在内存中使用相同大小的块。 ndarray中的每个元素是数据类型对象的对象(称为 dtype)。从ndarray对象提取的任何元素(通过切片)由一个数组标量类型的 Python 对象表示。 下图显示了ndarray,数据类型对象(dtype)和数组标量类型之间的关系。
import numpy as np
基本的ndarray是使用 NumPy 中的数组函数创建的
参数详解
参数 | 解释 |
---|---|
object | 任何暴露数组接口方法的对象都会返回一个数组或任何(嵌套)序列 |
dtype | 数组的所需数据类型,可选 |
copy | 可选,默认为true,对象是否被复制 |
order | C(按行)、F(按列)或A(任意,默认) |
subok | 默认情况下,返回的数组被强制为基类数组。 如果为true,则返回子类 |
ndimin | 指定返回数组的最小维数 |
a = np.array([1,2,3])#创建一维数组
a = np.array([[1, 2], [3, 4]]) #创建2维
a = np.array([1, 2, 3,4,5], ndmin = 2) #返回维数为2的数组
a = np.array([1, 2, 3], dtype = complex) #数组元素的类型为复数
4. 数据类型
NumPy 支持比 Python 更多种类的数值类型
5. 数组属性
【a.shape】
返回一个包含数组维度的元组,它也可以用于调整数组大小
a = np.array([[1,2,3],[4,5,6]])
a.shape
【a.reshape】
调整数组大小
a = np.array([[1,2,3],[4,5,6]])
a.reshape(1,6)
【a.ndim】
返回数组的维数
a = np.array([[1,2,3],[4,5,6]])
a.ndim
【a.itemsize】
返回数组中每个元素的字节单位长度。
a= np.array([1,2,3,4,5], dtype = np.int8)
a.itemsize
【a.flags】
展示当前的标志。
a = np.array([1,2,3,4,5])
a.flags
6. 数组创建
新的ndarray对象可以通过任何下列数组创建例程或使用低级ndarray构造函数构造。
参数详解
参数 | 解释 |
---|---|
Shape | 空数组的形状,整数或整数元组 |
Dtype | 所需的输出数组类型,可选 |
Order | 'C’为按行的 C 风格数组,'F’为按列的 Fortran 风格数组 |
【np.empty】
生成数组元素为随机值,因为它们未初始化
np.empty([3,2], dtype = int)
【np.zeros】
返回特定大小,以 0 填充的新数组
np.zeros(5, dtype = float, order = 'C') # 含有 5 个 0 的数组,默认类型为 float
np.zeros((5,), dtype = np.int)# 含有 5 个 0 的数组,默认类型为 np.int
np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')])# 自定义类型
【np.ones】
返回特定大小,以 1 填充的新数组。
np.ones(5, dtype = None, order = 'C')
7. 对现有数组进行操作
【np.asarray】
此函数类似于numpy.array,将 Python 序列转换为ndarray非常有用。
参数详解
参数 | 解释 |
---|---|
object | 任意形式的输入参数,比如列表、列表的元组、元组、元组的元组、元组的列表 |
dtype | 通常,输入数据的类型会应用到返回的ndarray |
Order | 'C’为按行的 C 风格数组,'F’为按列的 Fortran 风格数组 |
np.asarray(a, dtype = float, order = 'C')
x = (1,2,3) # 来自元组的 ndarray
a = np.asarray(x)
x = [(1,2,3),(4,5)] # 来自元组列表的 ndarray
a = np.asarray(x)
x = [1,2,3] # 来自元组列表的 ndarray
a = np.asarray(x)
【np.reshape】在不改变数据的条件下修改形状
a.reshape(4,2)
【np.ndarray.flat】返回数组上的一维迭代器,行为类似 Python 内建的迭代器。
a = np.arange(8).reshape(2,4)
a.flat[5]
【np.ndarray.flatten】返回折叠为一维的数组副本,函数接受下列参数
a.flatten(order = 'F')#以 F 风格顺序展开的数组
【np.ravel】返回展开的一维数组,并且按需生成副本。返回的数组和输入数组拥有相同数据类型。这个函数接受两个参数。(order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。)
a = np.arange(8).reshape(2,4)
a.ravel(order = 'F')#以 F 风格顺序调用 ravel 函数之后
【np】
【np】
【np】
【np】
【np】
【np】
【np】
【np】
8. 生成范围的数组
【np.arange】
np.arange(start, stop, step, dtype)
参数 | 解释 |
---|---|
start | 范围的起始值,默认为0 |
stop | 范围的终止值(不包含) |
step | 两个值的间隔,默认为1 |
dtype | 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。 |
x = np.arange(10,20,2,dtype = float)
【np.linspace】
此函数类似于arange()函数。 在此函数中,指定了范围之间的均匀间隔数量,而不是步长。
np.linspace(start, stop, num, endpoint, retstep, dtype)
参数 | 解释 |
---|---|
start | 序列的起始值 |
stop | 序列的终止值,如果endpoint为true,该值包含于序列中 |
num | 要生成的等间隔样例数量,默认为50 |
endpoint | 序列中是否包含stop值,默认为ture |
retstep | 如果为true,返回样例,以及连续数字之间的步长 |
dtype | 输出ndarray的数据类型 |
x = np.linspace(10,20, 5, endpoint = False, retstep = True,dtype = float)
【np.logspace】
此函数返回一个ndarray对象,其中包含在对数刻度上均匀分布的数字。 刻度的开始和结束端点是某个底数的幂,通常为 10。
np.logscale(start, stop, num, endpoint, base, dtype)
参数 | 解释 |
---|---|
start | 起始值是base ** start |
stop | 终止值是base ** stop |
num | 范围内的数值数量,默认为50 |
endpoint | 如果为true,终止值包含在输出数组当中 |
base | 对数空间的底数,默认为10 |
dtype | 输出数组的数据类型,如果没有提供,则取决于其它参数 |
np.logspace(1,10,num = 10, base = 2)
9. 切片和索引
ndarray对象的内容可以通过索引或切片来访问和修改
基本切片
通过将start,stop和step参数提供给内置的slice函数来构造一个 Python slice对象。 此slice对象被传递给数组来提取数组的一部分。
a = np.arange(10)
s = slice(2,7,2) #从索引2到7,步长为2。
a[s]
冒号分隔的切片
由冒号分隔的切片参数(start:stop:step)直接提供给ndarray对象,也可以获得相同的结果
a = np.arange(10)
b = a[2:7:2]
省略号切片
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
a[...,1]# 这会返回第二列元素的数组:
a[1,...]# 现在我们从第二行切片所有元素:
a[...,1:]# 现在我们从第二列向后切片所有元素:
10. 整数索引
每个整数数组表示该维度的下标值。
获取ndarray对象中每一行指定列的一个元素。 因此,行索引包含所有行号,列索引指定要选择的元素。
x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0,1,2], [0,1,0]] #数组中(0,0),(1,1)和(2,0)位置处的元素。
获取 4X3 数组中的每个角处的元素。 行索引是[0,0]和[3,3],而列索引是[0,2]和[0,2]。
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols] # 这个数组的每个角处的元素
使用slice作为列索引和高级索引。 当切片用于两者时,结果是相同的。 但高级索引会导致复制,并且可能有不同的内存布局。
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
x[1:4,1:3]# 切片
x[1:4,[1,2]]# 高级索引切片
11. 布尔索引
当结果对象是布尔运算(例如比较运算符)的结果时,将使用此类型的高级索引。
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
x[x > 5]# 大于 5 的元素会作为布尔索引的结果返回
a = np.array([np.nan, 1,2,np.nan,3,4,5])
a[~np.isnan(a)]#使用了~(取补运算符)来过滤NaN。
a = np.array([1, 2+6j, 5, 3.5+5j])
a[np.iscomplex(a)]# 从数组中过滤掉非复数元素
12. NumPy - 广播
广播是指 NumPy 在算术运算期间处理不同形状的数组的能力。 对数组的算术运算通常在相应的元素上进行。 如果两个阵列具有完全相同的形状,则这些操作被无缝执行。
如果两个数组的维数不相同,则元素到元素的操作是不可能的。 然而,在 NumPy 中仍然可以对形状不相似的数组进行操作,因为它拥有广播功能。 较小的数组会广播到较大数组的大小,以便使它们的形状可兼容。
如下面实际例子:
a = np.array([1,2,3,4])
b = np.array([10,20,30,40])
c = a * b
只有当两个数组的尾部维度时才会触发广播,否则报错
- 尾部维度
将多维数组右对齐!能够上下对应的这部分就是尾部维度。 - 头部维度
维度大的数组比维度小的数组多出来的维度!
a = np.array([[0.0,0.0,0.0],[10.0,10.0,10.0],[20.0,20.0,20.0],[30.0,30.0,30.0]])
b = np.array([1.0,2.0,3.0])
a+b
原理
13. 数组上的迭代
NumPy 包包含一个迭代器对象numpy.nditer。 它是一个有效的多维迭代器对象,可以用于在数组上进行迭代。 数组的每个元素可使用 Python 的标准Iterator接口来访问。
示例 1
a = np.arange(0,60,5)
a = a.reshape(3,4)
for x in np.nditer(a):
print(x)
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
修改后的数组是:
0 5 10 15 20 25 30 35 40 45 50 55
可以通过显式提醒,来强制nditer对象使用某种顺序:
# 以 C 风格顺序排序
for x in np.nditer(a, order = 'C'):
print(x)
# 以 F 风格顺序排序
for x in np.nditer(a, order = 'F'):
print(x)
以 C 风格顺序排序:
0 5 10 15 20 25 30 35 40 45 50 55
以 F 风格顺序排序:
0 20 40 5 25 45 10 30 50 15 35 55