数组 (Array)
数组是一组同种类型标量数值的有序集合,它有维度、轴(axis)及形状(shape) 等基本属性,与数学中的向量、矩阵和高阶张量等概念相对应。
PDE数值解种的很多算法,如FEM、FVM、FDM等算法的核心数据结构就是数组,核心的操作也是对数组的操作
数组化编程 (Array Programming)
- 数组化编程的基本思想是把运算操作一次性应用到整个数据结构上。
- 这种编程模型允许程序员以整个数据集合为思考和操作的对象,而不必求助于单个标量操作的显示循环。
- 标量化编程与数组化编程对比:
C中的两个矩阵相加
for (i=0; i<n; i++)
for (j=0; j<n; j++)
c[i][j] = a[i][j] + b[i][j];
Python中两矩阵相加
c = a + b
- 数组化编程对应计算机科学中的Single Instruction,Multiple Data(SIMD)
Numpy
- 简介
Numpy是Numerical Python的简称,他是目前Python数值计算中最为重要的基础软件包。大多数Python大数据和科学计算软件包都提供了基于Numpy的计算函数功能,并将Numpy的数组对象作为数据交换的通用形式。
import numpy as np
print(np._version_)
- Python内置数据结构
Python是一种解释性的动态类型语言,可自动化进行程序内存的分配和回收。这大大减轻了用户编程的负担,带来了极大的编程灵活性。 - C 和 Python 的不同
1)Python是一种动态类型的语言,变量的类型可以改变。
x=4
x="four"
2)C 是一种静态类型的语言,变量类型确定后就不能再改变。
int x-4
x = "four"; //错误
-
Python 中的整数不仅仅是一个整数
标准的Python是由 C 语言实现的,它的整数对象除了要表示的整数,还存储了很多其他信息,它的具体实现代码如下:
-
Python中的列表与Numpy数组
-
Python列表对象与Numpy数组对象有不同之处:
1)Numpy 数组对象包含了一个指向一块连续内存的指针,数组的所有数据就存储在这块内存中,这样不灵活,但数据的存储和操作更高效。
2)Python 列表对象包含一组指针,每个指针又指向一个Python 的对象这些对象又各自包含自己的数据和类型信息,这样带来极大的灵活性,但在数据存储和操作上损失了效率, -
多维数组对象:np.ndarray
Numpy提供一个多维数组对象ndarray,它是同种类型数据的一个有序集合。下面给出一个Numpy 数组的创建示例: -
多维数组对象:np.ndarray
计算机内存是一个线性结构,那么多维数组对象ndarray中的数据在内存中是如何存储的?要实现数组中元素的访问和操作,ndarray应该有什么样的属性?
在计算机内存中,上面的二维数组 a 是以一行接一行的方式存储在一块连续的内存当中,这种存储方式称为行优先 (row-major) 存储。
-
多维数组的数据类型:dtype
多维数组是用来存储同种类型数据的,同种类型的数据占有内存的大小是固定的。多维数组中的数据类型属性dtype规定了数组中的数据占用内存的大小,科学计算中常用的数据类型有:
np.bool_,长度8位,1个字节;
np.int_,长度64位,8个字节
np.float64,长度64位,8个字节
np.complex128,长度128位,16个字节
…
-
多维数组的轴 (axis)
1维数组1个轴,2维数组2个轴,n维数组n个轴。
数组的轴是有顺序的,编号从0开始。
数组的每一轴都是有长度的。
-
多维数组的 shape 和 strides 属性
a 有1个轴;a.shape=(3,);a.strides=(8,); -
多维数组对象的创建方法
np.array
np.arange
np.ones
np.ones_like
np.zeros
np.zeros_like
-
多维数组元素的索引
1)基础索引(basic indexing)a[1],a[2,1]
2)切片索引(slice indexing)a[1:],a[2:10:2]
3)布尔索引(bool indexing)a[a>0]
4)神奇索引(magic indexing)a[[2,4,2,5]]
5)省略索引(ellipsis indexing)a[…,1]
- 视图
Numpy为了提高内存利用率,尽量避免大数据的拷贝操作,在切片索引等一些操作中,返回的并不是原始数组的一个副本(copy),而是一个视图(view)。
1)多维数据的视图可以当做普通的多维数组使用。
2)但一定要注意,修改视图数组的元素,同时也会修改原始数组的对应元素。
3)而修改副本数组的元素,不会影响到原始数组的对应元素。
4)在Numpy中,能返回视图,尽量返回视图,如切片索引和省略索引返回的都是数组的视图。
5)在基于Numpy的科学计算程序设计中,要时刻明确,当前使用的数组是原始数组、副本数组和视图数组的哪一种。 - 数组中的广播(broadcasting)
Numpy中形状相同的数组可以逐元素地进行二元运算,而广播可以允许不同形状的数组在一定的规则下进行运算。
Numpy广播遵循一组严格的规则:
1)如果两个数组的维度数不相同,那么维数小的数组的形状将会在最左边补1.
2)如果两个数组的形状在任何一个维度上都不匹配,那么数组的形状会沿着维度为1的维度扩展以匹配另外一个数组的形状。
3)如果两个数组的形状在任何一个维度上都不匹配并且没有任何一个维度等于1,那么就会引发异常。
-
多维数组的组装
在科学计算中,有时我们需要创建一个数组,但我们仅知道一个数组的形状,以及一些位置应该放一些什么值,这时就需要用到Numpy提供的数组组装功能。
-
Numpy程序设计的一些基本原则
1)尽量避免复制数据。
2)默认为行优先存储。
3)利用视图和广播功能,尽量避免开辟新的内存。
4)利用数组化编程方式提高编写代码和程序执行的效率
爱因斯坦求和:np.einsum
爱因斯坦求和 (Einstein Summation) 是一种张量运算的维度标记约定,可以使张量运算的数学表达式更加简洁明快。
np.einsum是进行单元矩阵组装的利器!一定要熟练掌握!
稀疏矩阵
- 简介:给定一个矩阵A,如果其非零元个数比较少,就称其为稀疏矩阵。稀疏矩阵是数值计算中经常用到的矩阵类型,如有限元、有限差分、有限体积等常用的偏微分方程数值求解方法,最后得到的都是稀疏矩阵。
如果矩阵的总数据量较大,完成存储这个句子会有大量的0存储,会浪费很多空间。因此,我们需要为稀疏矩阵设计不同的存储格式。
1)坐标格式稀疏矩阵 Coordinate format Matrix(COO)
2)压缩稀疏行稀疏矩阵Compressed Sparse Row Matrix (CSR)
3)压缩稀疏列稀疏矩阵Compressed Sparse Column Matrix (CSC)