最近在看《Spark for Data Science》这本书,阅读到《Machine Learning》这一节的时候被稀疏矩阵的存储格式CSC给弄的晕头转向的。所以专门写一篇文章记录一下我对这种格式的理解。

目的

Compressed Sparse Column Format (CSC)的目的是为了压缩矩阵,减少矩阵存储所占用的空间。这很好理解,手法无法就是通过增加一些"元信息"来描述矩阵中的非零元素存储的位置(基于列),然后结合非零元素的值来表示矩阵。这样在一些场景下可以减少矩阵存储的空间。

Spark API

在Spark中我们一般创建这样的稀疏矩阵的API为:

   package org.apache.spark.ml.linalg
/**
* Creates a column-major sparse matrix in Compressed Sparse Column (CSC) format.
*
* @param numRows number of rows
* @param numCols number of columns
* @param colPtrs the index corresponding to the start of a new column
* @param rowIndices the row index of the entry
* @param values non-zero matrix entries in column major
*/
@Since("2.0.0")
def sparse(
numRows: Int,
numCols: Int,
colPtrs: Array[Int],
rowIndices: Array[Int],
values: Array[Double]): Matrix = {
new SparseMatrix(numRows, numCols, colPtrs, rowIndices, values)
}

使用CSC格式表示稀疏矩阵

例如我们想创建一下如下的3x3的稀疏矩阵:

	1	0	4
0 3 5
2 0 6

我们就可以使用上面的这个api:

	import org.apache.spark.ml.linalg.{Matrix,Matrices}
val sm: Matrix = Matrices.sparse(3,3, Array(0,2,3,6), Array(0,2,1,0,1,2), Array(1.0,2.0,3.0,4.0,5.0,6.0))
输出如下:
sm: org.apache.spark.ml.linalg.Matrix = 3 x 3 CSCMatrix
(0,0) 1.0
(2,0) 2.0
(1,1) 3.0
(0,2) 4.0
(1,2) 5.0
(2,2) 6.0

也就是说上面的3x3的矩阵,可以表示为下面3个数组:

	Array(0, 2, 3, 6)
Array(0, 2, 1, 0, 1, 2)
Array(1, 2, 3, 4, 5, 6)

说实话我第一次看到这个api的时候有点蒙。下面因为没太看懂上面三个Array中的第一个Array(0, 2, 3, 6)是怎么的出来的。也翻看了比较权威的资料(本文最下方的参考资料),但是感觉说的比较不清楚,因此下面谈谈我是如何理解的。

我的理解

上面的3个Array:(为了便于书写我没有写1.0,而是直接写为1)

	Array(0, 2, 3, 6)
Array(0, 2, 1, 0, 1, 2)
Array(1, 2, 3, 4, 5, 6)

其中第三个Array很好理解。它的值就是按照,依次按照顺序记录的矩阵中的非零值。

第二个Array也比较好理解,他表示的是每一列,非零元素所在的行号,行号从0开始。比如上面的矩阵中,第一列元素1在第0行,元素2在第2行。

至于第1个Array理解起来稍微麻烦一些。我的总结就是:

  • 第一个Array的元素个数就是(矩阵的列数+1),也就是矩阵是3列,那么这个Array的个数就是4.
  • 第一个元素一直是0。第二个元素是第一列的非零元素的数量
  • 后续的值为前一个值 + 下一列非零元素的数量

上面的总结可能看起来比较模糊,根据上面的例子我来分析一下:

  • 首先矩阵的3x3的,所以第一个Array会有4个元素。第一个元素是0。得到Array(0)。
  • 矩阵第一列有2个非零元素,所以得到Array的第二个元素为2.得到Array(0, 2)
  • 矩阵的第二列有1个非零元素,那么第三个元素的数量为当前Array的最后一个元素加1,也就是2 + 1=3. 得到Array(0,2, 3)
  • 矩阵的第三列有3个非零元素,那么Array的最后一个元素的值为 3 + 3 = 6. 得到Array(0, 2, 3, 6)

验证例子

对于下面的这个3x3的矩阵:

	1	0	2
0 0 3
4 5 6

我们可以得到3个Array为:

Array(0, 2, 3, 6)
Array(0, 2, 2, 0, 1, 2)
Array(1, 4, 5, 2, 3, 6)

对于下面的矩阵:

	9	0
0 8
0 6

我们可以得到3个Array来表示他:

	Array(0, 1, 3)
Array(0, 1, 2)
Array(9, 8, 6)

对于下面的矩阵:

	9	0	0	0
0 8 6 5

我们可以表示为:

	Array(0, 1, 2, 3, 4)
Array(0, 1, 1, 1)
Array(9, 8, 6, 5)

根据CSC表示法,画出原始矩阵

上面展示了如何把稀疏矩阵使用CSC表示,那么反过来应该怎么操作呢,

假设有一个2x4的矩阵,他的CSC表示为:

	Array(0, 1, 2, 3, 4)
Array(0, 1, 1, 1)
Array(9, 8, 6, 5)

我大致描述一下还原的过程:

  • 首先我们知道是2x4的矩阵,并且第一个Array的第二个元素是1,而且后续的每一个元素都比前一个元素大1,说明每一列都只有1个非零元素。
  • 根据第二个数组,我们可以知道只有第一列的非零元素在第一行,2,3,4列的非零元素都在第二行
  • 根据第三个Array,我们就可以比较简单的画出原始矩阵。

参考资料

理解Compressed Sparse Column Format (CSC)的更多相关文章

  1. sparse matrix format

    see Spare Matrix wikipedia item, and scipy's documentation on different choices of sparse matrix typ ...

  2. SSIS 中将csv 文件批量导出到excel 文件,并设置excel 文件中某些列的data column format 为Text

    csv 文件是文本文件类型,但是打开csv 文件后(默认使用本地已经安装的excel 来打开excel 文件),默认显示出来的是general 类型(column data format)的数据, 这 ...

  3. SharePoint Column Format

    https://docs.microsoft.com/en-us/sharepoint/dev/declarative-customization/column-formatting . { &quo ...

  4. Only POT texture can be compressed to PVRTC format

    在图片压缩格式 报这个Warning的时候,意思是该图片必须要采用2的幂次方大小才能使用该格式. POT: Power of Two. 采取方式是在advanced里边,把Non Power of 2 ...

  5. 稀疏矩阵 part 1

    ▶ 图片参考[http://www.bu.edu/pasi/files/2011/01/NathanBell1-10-1000.pdf] ▶ 各种系数矩阵的数据结构 ● MAT,原始矩阵数据 type ...

  6. scipy稀疏矩阵

    那些零元素数目远远多于非零元素数目,并且非零元素的分布没有规律的矩阵称为稀疏矩阵(sparse matrix). 不同类型的矩阵有不同的压缩方式,比如对角矩阵只存储对角元素即可.要想充分压缩,就要找到 ...

  7. sklearn文本特征提取

    http://cloga.info/2014/01/19/sklearn_text_feature_extraction/ 文本特征提取 词袋(Bag of Words)表征 文本分析是机器学习算法的 ...

  8. Feature extraction - sklearn文本特征提取

    http://blog.csdn.net/pipisorry/article/details/41957763 文本特征提取 词袋(Bag of Words)表征 文本分析是机器学习算法的主要应用领域 ...

  9. 稀疏矩阵在Python中的表示方法

    对于一个矩阵而言,若数值为零的元素远远多于非零元素的个数,且非零元素分布没有规律时,这样的矩阵被称作稀疏矩阵:与之相反,若非零元素数目占据绝大多数时,这样的矩阵被称作稠密矩阵. 稀疏矩阵在工程应用中经 ...

随机推荐

  1. css和@import区别用法

    css和@import都是调用外部样式表的方法. 一.用法 (1)link: <link rel="stylesheet" type="text/css" ...

  2. dotnet core 使用 MongoDB 进行高性能Nosql数据库操作

    好久没有写过Blog, 每天看着开源的Java社区流口水, 心里满不是滋味. 终于等到了今年六月份 dotnet core 的正式发布, 看着dotnet 社区也一步一步走向繁荣, 一片蒸蒸日上的大好 ...

  3. 提交本地项目到github服务器

    已经完成的本地项目 提交到github 并不是按照先在github上创建一个仓库 然后clone下来的顺序 1.在github上创建仓库 2.在本地项目初始化git仓库 $ git init 3.添加 ...

  4. 在Ubuntu和Linux Mint上安装Oracle JDK

    在Ubuntu和Linux Mint上安装Oracle JDK 使用下面的命令安装,只需一些时间,它就会下载许多的文件,所及你要确保你的网络环境良好: sudo add-apt-repository ...

  5. Android笔记——Android自定义控件

    目录: 1.自定义控件概述 01_什么是自定义控件 Android系统中,继承Android系统自带的View或者ViewGroup控件或者系统自带的控件,并在这基础上增加或者重新组合成我们想要的效果 ...

  6. Java之this关键字的用法

    Java 中的 this 关键字指当前的对象,可以直接用其调用当前对象的成员变量,也可以直接用其调用当前对象的成员方法,这是我们常见的场景,那么有没有其它的情况呢! this 还可以在无参的构造方法中 ...

  7. jsTree简单应用Demo

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...

  8. Unix&Linux技术文章目录(2015-12-22更新)

    Unix & Linux 方面的博客整理.归纳分类,要坚持不懈的学习Unix &Linux,加油!技术需要累积和沉淀.更需要锲而不舍的精神.持之以恒的毅力!借此下面名句勉励自己! 书上 ...

  9. mysql 触发器

    触发器(trigger)是SQL server 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发, 比如当 ...

  10. ubuntu下修改键位

    尴尬的背景: 服役5年的笔记本,最近键盘失灵,部分键位彻底失去响应.最蛋疼的是左右方向键都不能用了 ○| ̄|_ 解决方案是,通过xmodmap命令,用其他相对鸡肋些的键位替代方向键. 1 查看各个键位 ...