项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
欢迎大家star,留言,一起学习进步

spark mllib模块中,矩阵的表示位于org.apache.spark.mllib.linalg包的Matrices中。而Matrix的表示又分两种方式:dense与sparse。在实际场景应用场景中,因为大数据本身的稀疏性,sparse的方式比dense的方式使用更为频繁。而网络上大部分的资料对与sparse方式解释不是很清晰,本人也花了一些时间来理解,所以特此记录。

1.稀疏矩阵的一些表达方式

1.1 coo

这种方式构造稀疏矩阵很容易理解,需要三个等长数组,alues数组存放矩阵中的非0元素,row indices存放非0元素的行坐标,column indices存放非0元素的列坐标。
这种方式的优点:
1.容易构造
2.可以快速地转换成其他形式的稀疏矩阵
3.支持相同的(row,col)坐标上存放多个值
缺点如下:
1.构建完成后不允许再插入或删除元素
2.不能直接进行科学计算和切片操作

1.2 csr_matrix

csr_matrix同样由3个数组组成,values存储非0元素,column indices存储非0元素的列坐标,row offsets依次存储每行的首元素在values中的坐标,如果某行全是0则对应的row offsets值为-1。
这种方式的优点:
1.高效地按行切片
2.快速地计算矩阵与向量的内积
3.高效地进行矩阵的算术运行,CSR + CSR、CSR * CSR等
缺点:
1.按列切片很慢(考虑CSC)
2.一旦构建完成后,再往里面添加或删除元素成本很高

1.3 csc_matrix

csr是基于行,则csc是基于列,特点自然跟csr_matrix类似。

1.4 dia_matrix

对角线存储法,按对角线方式存,列代表对角线,行代表行。省略全零的对角线。
适用场景:
如果原始矩阵就是一个对角性很好的矩阵那压缩率会非常高,比如下图,但是如果是随机的那效率会非常糟糕。

当然还有根据各种场景合适的存储方式,这里就不再一一列举了。

2.spark中的稀疏矩阵表达

mllib中,稀疏矩阵可以用Matrices.sparse来生成。
先看看SparseMatrix的源码:

class SparseMatrix @Since("1.3.0") (@Since("1.2.0") val numRows: Int,@Since("1.2.0") val numCols: Int,@Since("1.2.0") val colPtrs: Array[Int],@Since("1.2.0") val rowIndices: Array[Int],@Since("1.2.0") val values: Array[Double],@Since("1.3.0") override val isTransposed: Boolean) extends Matrix {require(values.length == rowIndices.length, "The number of row indices and values don't match! " +s"values.length: ${values.length}, rowIndices.length: ${rowIndices.length}")// The Or statement is for the case when the matrix is transposedrequire(colPtrs.length == numCols + 1 || colPtrs.length == numRows + 1, "The length of the " +"column indices should be the number of columns + 1. Currently, colPointers.length: " +s"${colPtrs.length}, numCols: $numCols")require(values.length == colPtrs.last, "The last value of colPtrs must equal the number of " +s"elements. values.length: ${values.length}, colPtrs.last: ${colPtrs.last}")/*** Column-major sparse matrix.* The entry values are stored in Compressed Sparse Column (CSC) format.* ...

上面代码的注释中,透露了一个很重要的信息:spark mllib中的稀疏矩阵是通过CSC的格式存储的!

在spark shell中测试一下:

scala> import org.apache.spark.mllib.linalg.Matrices
import org.apache.spark.mllib.linalg.Matricesscala> val mx = Matrices.sparse(2,4, Array(0, 1, 2, 3, 4),Array(0, 1, 1, 1), Array(9, 8, 6, 5))
mx: org.apache.spark.mllib.linalg.Matrix =
2 x 4 CSCMatrix
(0,0) 9.0
(1,1) 8.0
(1,2) 6.0
(1,3) 5.0

根据源码可以看出,构造一个稀疏矩阵需要5个参数,分别为行、列,colPtrs为每列的首元素在values中的坐标,rowIndices为每个元素的行坐标,values为对应的值。

3.如果有每行/每列均为0怎么办

CSC这种方式在存储矩阵的时候,有三个数组。最开始的时候,我想到一个问题:如果只存这三个数组,能完整表示这个稀疏矩阵么?
答案是不能。为什么呢?这个问题经过作者深入思考,原因如下。
比如上面的矩阵为一个2*4的矩阵,具体形式为:
9 0 0 0
0 8 6 5
如果给上面矩阵添加一行全0行,
9 0 0 0
0 8 6 5
0 0 0 0
大家会发现这个稀疏矩阵按CSC的方式存储,对应的三个数组与上面的矩阵是一样的!
因为colPtrs为矩阵的列数+1,所以如果只存三个数组,只能确定矩阵的列数,无法确定矩阵的行数,矩阵往后面追加再多的全0行,对应的三个数组都是一样的!
所以在构造方法中,才会要求指定矩阵的行数与列数!
我们可以在spark shell中再尝试一下:

scala> val mx = Matrices.sparse(3,4, Array(0, 1, 2, 3, 4),Array(0, 1, 1, 1), Array(9, 8, 6, 5))
mx: org.apache.spark.mllib.linalg.Matrix =
3 x 4 CSCMatrix
(0,0) 9.0
(1,1) 8.0
(1,2) 6.0
(1,3) 5.0scala> val mx = Matrices.sparse(4,4, Array(0, 1, 2, 3, 4),Array(0, 1, 1, 1), Array(9, 8, 6, 5))
mx: org.apache.spark.mllib.linalg.Matrix =
4 x 4 CSCMatrix
(0,0) 9.0
(1,1) 8.0
(1,2) 6.0
(1,3) 5.0

我们不改变后面三个数组的值,只改变构造函数中的行数,可以看出就构造除了不同的稀疏矩阵!

spark 稀疏矩阵存储详细解读相关推荐

  1. Spark知识体系完整解读

    Spark知识体系完整解读(内有福利) 作者:杨思义,2014年6月至今工作于北京亚信智慧数据科技有限公司 BDX大数据事业部,从2014年9月开始从事项目spark相关应用开发. 来源:数盟 Spa ...

  2. 刚刚,OpenStack 第 19 个版本来了,附28项特性详细解读!

    刚刚,OpenStack 第 19 个版本来了,附28项特性详细解读! OpenStack Stein版本引入了新的多云编排功能,以及帮助实现边缘计算用例的增强功能. OpenStack由一系列相互关 ...

  3. VINS-mono详细解读与实现

    VINS-mono详细解读 VINS-mono详细解读 前言 Vins-mono是香港科技大学开源的一个VIO算法,https://github.com/HKUST-Aerial-Robotics/V ...

  4. MemCache超详细解读

    MemCache是什么 MemCache是一个自由.源码开放.高性能.分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高 ...

  5. MemCache详细解读

    MemCache是什么 MemCache是一个自由.源码开放.高性能.分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高 ...

  6. 海量结构化数据解决方案-表格存储场景解读

    简介: 数据是驱动业务创新的最核心的资产.不同类型的数据如非结构化数据(视频.图片等).结构化数据(订单.轨迹),面向不同业务的使用要求需要选择适合的存储引擎,能够真正发挥数据的价值.针对于海量的非强 ...

  7. 个性化联邦学习PFedMe详细解读(NeurIPS 2020)

    关注公众号,发现CV技术之美 本文介绍一篇 NeurIPS 2020 的论文『Personalized Federated Learning with Moreau Envelopes』,对个性化联邦 ...

  8. 经典神经网络论文超详细解读(三)——GoogLeNet InceptionV1学习笔记(翻译+精读+代码复现)

    前言 在上一期中介绍了VGG,VGG在2014年ImageNet 中获得了定位任务第1名和分类任务第2名的好成绩,而今天要介绍的就是同年分类任务的第一名--GoogLeNet . 作为2014年Ima ...

  9. 强化学习 - 详细解读DQN(更新完成)

    详细解读DQN 一. 强化学习 1. 什么是强化学习问题? 2. 强化学习的理论体系 (1) MDP i) Markov Property ii) Markov Process iii) Markov ...

  10. vins 解读_VINS-mono详细解读

    VINS-mono详细解读 极品巧克力 前言 Vins-mono是香港科技大学开源的一个VIO算法,https://github.com/HKUST-Aerial-Robotics/VINS-Mono ...

最新文章

  1. Linux执行可执行文件提示No such file or directory的解决方法
  2. Superset配置impala数据源
  3. linux 主进程 等待,Linux启动与进程
  4. python中函数重载和重写
  5. XSS跨站脚本(web应用)——XSS相关工具及使用(四)
  6. python3 批量定义多个变量_Python3 基本数据类型详解
  7. 判断输入的日期字符串是否小于当前日期
  8. 使用spring-boot-maven-plugin插件打包spring boot项目
  9. 软件项目管理 案例教程复习要点
  10. c语言的整形变量选择题,C语言选择题 (附答案)
  11. mysql no database selected_数据库中出现no database selected是什么意思?
  12. Tri-Training: Exploiting Unlabeled Data Using Three Classifiers
  13. ORA-29913,ORA-29400,KUP-00554,KUP-01005,KUP-01007 oracle外部表报错解决记录
  14. DS5000神奇的FDE全磁盘加密技术
  15. Round-Robin算法的verilog实现
  16. 在reader.onload中的定义的变量如何在外部调用
  17. linux里实现sl跑火车
  18. Android开发调用手机上安装的地图应用导航
  19. 恒玄BES调试笔记-BES2500死机重启分析手段
  20. 百度Q2财报发布后,股价惨不忍睹,首席战略官是否为虚职?

热门文章

  1. Windows Server 2012 搭建DHCP及远程路由访问
  2. redis的其他功能
  3. [译]应用内搜索功能实现 Android TV应用程序手册教程十三
  4. 【网络优化|渣速必看】合理设置MTU,提升网络速度
  5. 手机圈老兵任伟光加盟联想
  6. 独角兽复活:Twilio上市预示IPO市场起死回生
  7. iphone 如何卸载xcode4.2
  8. 多个线程交替打印ABC,打印10次
  9. DB2 在创建数据库的时候,后面不能加“;”分号
  10. css 的块级元素和行内元素