一、关于稀疏矩阵的学习
稀疏矩阵是指矩阵中的元素大部分是0的矩阵,事实上,实际问题中大规模矩阵基本上都是稀疏矩阵,很多稀疏度在90%甚至99%以上。因此我们需要有高效的稀疏矩阵存储格式。几种典型的格式:COO,CSR,DIA,ELL,HYB
(1)COO
这是最简单的一种格式,每一个元素需要用一个三元组来表示,分别是(行号,列号,数值),对应上图右边的一列。这种方式简单,但是记录单信息多(行列),每个三元组自己可以定位,因此空间不是最优。
(2)CSR
CSR是比较标准的一种,也需要三类数据来表达:数值,列号,以及行偏移。CSR不是三元组,而是整体的编码方式。数值和列号与COO一致,表示一个元素以及其列号,行偏移表示某一行的第一个元素在values里面的起始偏移位置。如上图中,第一行元素1是0偏移,第二行元素2是2偏移,第三行元素5是4偏移,第4行元素6是7偏移。在行偏移的最后补上矩阵总的元素个数,本例中是9。
(逐行排列,偏移值为排列在该元素前面的元素数)
CSC是和CSR相对应的一种方式,即按列压缩的意思。对应上面的按行压缩。
(3)ELL
用两个和原始矩阵相同行数的矩阵来存:第一个矩阵存的是列号,第二个矩阵存的是数值,行号就不存了,用自身所在的行来表示;这两个矩阵每一行都是从头开始放,如果没有元素了就用个标志比如*结束。 上图中间矩阵有误,第三行应该是 0 2 3。
注:这样如果某一行很多元素,那么后面两个矩阵就会很胖,其他行结尾*很多,浪费。可以存成数组,比如上面两个矩阵就是
(4)DIA
对角线存储法,按对角线方式存,列代表对角线,行代表行。省略全零的对角线。(从左下往右上开始:第一个对角线是零忽略,第二个对角线是5,6,第三个对角线是零忽略,第四个对角线是1,2,3,4,第五个对角线是7,8,9,第六第七个对角线忽略)。[3]
这里行对应行,所以5和6是分别在第三行第四行的,前面补上无效元素*。如果对角线中间有0,存的时候也需要补0,所以如果原始矩阵就是一个对角性很好的矩阵那压缩率会非常高,比如下图,但是如果是随机的那效率会非常糟糕。
- Hybrid (HYB) ELL + COO
为了解决(3)ELL中提到的,如果某一行特别多,造成其他行的浪费,那么把这些多出来的元素(比如第三行的9,其他每一行最大都是2个元素)用COO单独存储。
选择稀疏矩阵存储格式的一些经验:
1.DIA和ELL格式在进行稀疏矩阵-矢量乘积(sparse matrix-vector products)时效率最高,所以它们是应用迭代法(如共轭梯度法)解稀疏线性系统最快的格式;
2.COO和CSR格式比起DIA和ELL来,更加灵活,易于操作;
3.ELL的优点是快速,而COO优点是灵活,二者结合后的HYB格式是一种不错的稀疏矩阵表示格式;
4. 根据 Nathan Bell的工作 ,CSR格式在存储稀疏矩阵时非零元素平均使用的字节数(Bytes per Nonzero Entry)最为稳定(float类型约为8.5,double类型约为12.5),而DIA格式存储数据的非零元素平均使用的字节数与矩阵类型有较大关系,适合于StructuredMesh结构的稀疏矩阵(float类型约为4.05,double类型约为8.10),对于Unstructured Mesh以及Random Matrix,DIA格式使用的字节数是CSR格式的十几倍;
5.COO格式常用于从文件中进行稀疏矩阵的读写,如matrix market即采用COO格式,而CSR格式常用于读入数据后进行稀疏矩阵计算。
#COO CSR代码
from scipy import sparse
import numpy as np
# 创建一个numpy二维数组,对角线为1其余都为0
eye = np.eye(4)
print("NumPy array:\n", eye)
#将numpy数组转换为csr格式的scipy稀疏矩阵
#只保留非零元素
sparse_matrix = sparse.csr_matrix(eye)
print("\nscipy saprse csr matrix:\n{}".format
(sparse_matrix))
#创建COO格式的稀疏矩阵
data=np.ones(4)
row_indices=np.arange(4)
col_indices=np.arange(4)
eye_coo=sparse.coo_matrix((data, (row_indices,
col_indices)))
print("COO representation:\n{}".format(eye_coo))
- Matplotlib
完成可视化内容
plot
参数 含义
x X轴数据
y Y轴数据,要与X数据的长度一致
alpha 线条透明度,浮点值
color or c 颜色,十六进制或者字符串等
label 曲线名称,显示legend时有用
linewidth or lw 线条宽度,浮点数
linestyle or ls 线条样式
marker 数据点的样式
zorder 显示优先级,图内多种元素显示时控制元素的覆盖顺序
代码
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-10, 10, 100)
# 在-10和10之间生成一个数列,共100个数
y = np.sin(x)
# 用正弦函数创建第二个数组
plt.plot(x, y, marker="x")
plt.plot(x, y, marker="*")#marker 为图中点的标记形状
#plot函数绘制一个数组关于另一个数组的折线图
plt.show()
- Pandas
pandas是用于处理和分析数据的Python库。它基于一种叫作DataFrame的数据结构,这种数据结构模仿了R语言中的DataFrame。简单来说,一个pandasDataFrame是一张表格,类似于Excel表格。pandas中包含大量用于修改表格和操作表格的方法,尤其是可以像SQL一样对表格进行查询和连接。NumPy要求数组中的所有元素类型必须完全相同,而pandas不是这样,每一列数据的类型可以互不相同(比如整型、日期、浮点数和字符串)。pandas的另一个强大之处在于,它可以从许多文件格式和数据库中提取数据,如SQL、Excel文件和逗号分隔值(CSV)文件
代码
import pandas as pd
from IPython.display import display
# 创建关于人的简单数据集
data = {'Name': ["John", "Anna", "Peter", "Linda"],
'Location': ["New York", "Paris", "Berlin", "London"],
'Age': [24, 13, 53, 33]
}
data_pandas = pd.DataFrame(data)
# IPython.display allows "pretty printing" of dataframes
# in the Jupyter notebook
display(data_pandas)
- Mglearn
快速美化绘图,或者用于获取一些有趣的数据。
下载
pip install melean
代码默认引入
Import numpy as np
Import matplotlib.pyplot as plt
Import pandas as pd
Import mglearn