理解Compressed Sparse Column Format (CSC)
最近在看《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)的更多相关文章
- sparse matrix format
see Spare Matrix wikipedia item, and scipy's documentation on different choices of sparse matrix typ ...
- SSIS 中将csv 文件批量导出到excel 文件,并设置excel 文件中某些列的data column format 为Text
csv 文件是文本文件类型,但是打开csv 文件后(默认使用本地已经安装的excel 来打开excel 文件),默认显示出来的是general 类型(column data format)的数据, 这 ...
- SharePoint Column Format
https://docs.microsoft.com/en-us/sharepoint/dev/declarative-customization/column-formatting . { &quo ...
- Only POT texture can be compressed to PVRTC format
在图片压缩格式 报这个Warning的时候,意思是该图片必须要采用2的幂次方大小才能使用该格式. POT: Power of Two. 采取方式是在advanced里边,把Non Power of 2 ...
- 稀疏矩阵 part 1
▶ 图片参考[http://www.bu.edu/pasi/files/2011/01/NathanBell1-10-1000.pdf] ▶ 各种系数矩阵的数据结构 ● MAT,原始矩阵数据 type ...
- scipy稀疏矩阵
那些零元素数目远远多于非零元素数目,并且非零元素的分布没有规律的矩阵称为稀疏矩阵(sparse matrix). 不同类型的矩阵有不同的压缩方式,比如对角矩阵只存储对角元素即可.要想充分压缩,就要找到 ...
- sklearn文本特征提取
http://cloga.info/2014/01/19/sklearn_text_feature_extraction/ 文本特征提取 词袋(Bag of Words)表征 文本分析是机器学习算法的 ...
- Feature extraction - sklearn文本特征提取
http://blog.csdn.net/pipisorry/article/details/41957763 文本特征提取 词袋(Bag of Words)表征 文本分析是机器学习算法的主要应用领域 ...
- 稀疏矩阵在Python中的表示方法
对于一个矩阵而言,若数值为零的元素远远多于非零元素的个数,且非零元素分布没有规律时,这样的矩阵被称作稀疏矩阵:与之相反,若非零元素数目占据绝大多数时,这样的矩阵被称作稠密矩阵. 稀疏矩阵在工程应用中经 ...
随机推荐
- datatables中的Options总结(3)
datatables中的Options总结(3) 十.ColReorder colReorder.fixedColumnsLeft 不允许x列重新排序(从左数) colReorder.fixedCol ...
- CuPlayer
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <met ...
- 在Visual Studio 2015 中添加SharePoint 2016 开发模板
前言 SharePoint 2016已经发布很久了,然而,默认安装VS2015以后,却没有SharePoint 2016的开发模板.其实问题很简单,和VS2012开发SharePoint 2013一样 ...
- ViewPager之引导页
一.概述 ViewPager是android-support-v4中提供的类,它是一个容器类,常用于页面之间的切换. 本文介绍ViewPager最基础的应用:在多个View之间进行切换,亦即ViewP ...
- JavaSE 之 final 初探
我们先看一道面试题: 请问 final 的含义是什么?可以用在哪里?其初始化的方式有哪些? 首先我们回答一下这道题,然后再探究其所以然. 1.final 表示“最终的”.“不可改变的”,意指其修饰类 ...
- paramiko 的使用
paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient 用于远程连接机器执行基本命令,也可以执行shell脚本 基于用户名密码连接: def ssh_connect ...
- PriorityQueue和Queue的一种变体的实现
队列和优先队列是我们十分熟悉的数据结构.提供了所谓的“先进先出”功能,优先队列则按照某种规则“先进先出”.但是他们都没有提供:“固定大小的队列”和“固定大小的优先队列”的功能. 比如我们要实现:记录按 ...
- 安卓Android科大讯飞语音识别代码使用详解
科大讯飞的语音识别功能用在安卓代码中,我把语音识别写成了Service,然后在Fragment直接调用service服务.科大讯飞语音识别用的是带对话框的那个,直接调用科大讯飞的语音接口,代码采用链表 ...
- JAVA操作LDAP的详解(JLDAP)
最近两周由于要学习测试LDAP,所以对于用脚本操作LDAP很感兴趣,所以就做了一些脚本,都是比较简单的脚本吧. 废话不多说了哈.直接上教程 首先声明:我使用的是JLDAP操作LDAP,所以需要从官网下 ...
- L1-006. 连续因子
https://www.patest.cn/contests/gplt/L1-006 题目地址 在上面 一个正整数N的因子中可能存在若干连续的数字.例如630可以分解为3*5*6*7,其中5.6.7就 ...