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

稀疏矩阵在工程应用中经常被使用,尤其是在通信编码和机器学习中。若编码矩阵或特征表达矩阵是稀疏矩阵时,其计算速度会大大提升。对于机器学习而言,稀疏矩阵应用非常广,比如在数据特征表示、自然语言处理等领域。用稀疏表示和工作在计算上代价很高,需要专门处理稀疏矩阵的表示和操作等,但是这些操作可以大幅提升性能。

Python中的稀疏矩阵

SciPy使用多个数据结构为创建稀疏矩阵提供了工具,以及将稠密矩阵转化为稀疏矩阵的工具。许多在Numpy数组上运行的线性代数Numpy和SciPy函数可以在SciPy稀疏数组上操作。此外,使用Numpy数据结构的机器学习库也可以在Scipy稀疏数组上操作,例如,用于机器学习的scikit-learning和用于深度学习的Keras。

Scipy中有可以表示的7种稀疏矩阵类型:

  1. csc_matrix: Compressed Sparse Column format
  2. csr_matrix: Compressed Sparse Row format
  3. bsr_matrix: Block Sparse Row format
  4. lil_matrix: List of Lists format
  5. dok_matrix: Dictionary of Keys format
  6. coo_matrix: COOrdinate format (aka IJV, triplet format)
  7. dia_matrix: DIAgonal format

下面介绍常用的几种稀疏矩阵类型:

coo_matrix

coo_matrix是最简单的存储方式。采用三个数组row、col和data保存非零元素的行下标,列下标与值。这三个数组的长度相同。一般来说,coo_matrix主要用来创建矩阵,因为coo_matrix无法对矩阵的元素进行增删改等操作,一旦创建之后,除了将之转换成其它格式的矩阵,几乎无法对其做任何操作和矩阵运算

>>> row = [0, 1, 2, 2]
>>> col = [0, 1, 2, 3]
>>> data = [1, 2, 3, 4]
# 生成coo格式的矩阵
>>> coo_mat = sparse.coo_matrix((data, (row, col)), shape=(4, 4))
>>> coo_mat
<4x4 sparse matrix of type '<class 'numpy.int32'>'
with 4 stored elements in COOrdinate format>
>>> coo_mat.toarray()
array([[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 4],
[0, 0, 0, 0]])

优点:

  • 转换成其它存储格式很快捷简便,转换成csr/csc很快
  • 允许重复的索引(例如在1行1列处存了值2.0,又在1行1列处存了值3.0,则转换成其它矩阵时就是2.0+3.0=5.0)

缺点:

  • 不支持切片和算术运算操作

dok_matrix与lil_matrix

dok_matrix和lil_matrix适用的场景是逐渐添加矩阵的元素。dok_matrix的策略是采用字典来记录矩阵中不为0的元素。所以字典的key存的是记录元素的位置信息的元祖,value是记录元素的具体值。

>>> S = sparse.dok_matrix((5, 5), dtype=np.float32)
>>> for i in range(5):
for j in range(5):
S[i,j] = i+j # 更新元素 >>> S.toarray()
[[0. 1. 2. 3. 4.]
[1. 2. 3. 4. 5.]
[2. 3. 4. 5. 6.]
[3. 4. 5. 6. 7.]
[4. 5. 6. 7. 8.]]

优点:

  • 对于递增的构建稀疏矩阵很高效,比如定义该矩阵后,想进行每行每列更新值,可用该矩阵。当访问某个单元,只需要O(1)

缺点:

  • 不允许重复索引(coo中适用),但可以很高效的转换成coo后进行重复索引

lil_matrix则是使用两个列表存储非0元素。data保存每行中的非零元素,rows保存非零元素所在的列。这种格式也很适合逐个添加元素,并且能快速获取行相关的数据。

>>> l = sparse.lil_matrix((4, 4))
>>> l[1, 1] = 1
>>> l[1, 3] =2
>>> l[2, 3] = 3
>>> l.toarray()
array([[0., 0., 0., 0.],
[0., 1., 0., 2.],
[0., 0., 0., 3.],
[0., 0., 0., 0.]])

优点:

  • 适合递增的构建成矩阵
  • 转换成其它存储方式很高效
  • 支持灵活的切片

缺点:

  • 当矩阵很大时,考虑用coo
  • 算术操作,列切片,矩阵向量内积操作慢

csr_matrix与csc_matrix

csr_matrix是按行对矩阵进行压缩的,csc_matrix是按列对矩阵进行压缩的。通过row_offsets,column_indices,data来确定矩阵。column_indices,data与coo格式的列索引与数值的含义完全相同,row_offsets表示元素的行偏移量。

用如下例子说明:

>>> indptr = np.array([0, 2, 3, 6]) # 元素的行偏移量
>>> indices = np.array([0, 2, 2, 0, 1, 2]) # 列索引
>>> data = np.array([1, 2, 3, 4, 5, 6])
>>> csr_matrix((data, indices, indptr), shape=(3, 3)).toarray()
array([[1, 0, 2],
[0, 0, 3],
[4, 5, 6]])

以官方文档为例,此时data代表的是存储的值的数组,indices代表的是每一行中第几列有对应data中的元素,即从indices中可以推断出列的信息,indptr则用来推断出行的信息,默认元素开始为0,第一个元素为2,则证明第一行中有2-0=2个元素,所以将data数组中前另个元素写入第一行中,而indices前两个元素为0,2,则代表第0列和第2列。前两第二个元素为3,证明第二行中有3-2=1个元素,该元素为data[2]=3,且存储在indices[2] = 2列中。依次类推。

CSR格式常用于读入数据后进行稀疏矩阵计算。

CSR:

优点:

  • 高效的稀疏矩阵算术操作
  • 高效的行切片
  • 快速地矩阵向量内积操作

缺点:

  • 缓慢地列切片操作(可以考虑csc)
  • 转换到稀疏结构代价较高(可以考虑lil,dok)

CSC:

优点:

  • 高效的稀疏矩阵算术操作
  • 高效的列切片
  • 快速地矩阵向量内积操作(不如csr,bsr块)

缺点:

  • 缓慢地行切片操作(可以考虑csr)
  • 转换到稀疏结构代价较高(可以考虑lil,dok)

稀疏矩阵的存取

用save_npz保存单个稀疏矩阵

>>> scipy.sparse.save_npz('sparse_matrix.npz', sparse_matrix)
>>> sparse_matrix = scipy.sparse.load_npz('sparse_matrix.npz')

参考:

python稀疏矩阵的存储与表示

机器学习稀疏矩阵简介

稀疏矩阵在Python中的表示方法的更多相关文章

  1. Python中的__new__()方法与实例化

    @Python中的__new__()方法与实例化   __new__()是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在Python 中 存在于类里面的构造方法__init__ ...

  2. python中的replace()方法的使用

    python中的replace()方法的使用 需求是这样的:需要将字符串的某些字符替换成其他字符 str.replace(old,new,max) 第一个参数是要进行更换的旧字符,第二个参数是新的子串 ...

  3. Python中的字符串方法

    Python中的字符串方法 字符串类即str提供了许多有用的方法来操纵字符串.具体来说,我们将讨论如下的方法. 搜索字符串内的子字符串. 测试字符串. 格式字符串. 转换字符串. 回顾前面的章节,方法 ...

  4. python中的sort方法

    Python中的sort()方法用于数组排序,本文以实例形式对此加以详细说明: 一.基本形式 列表有自己的sort方法,其对列表进行原址排序,既然是原址排序,那显然元组不可能拥有这种方法,因为元组是不 ...

  5. python中的sort方法使用详解

    Python中的sort()方法用于数组排序,本文以实例形式对此加以详细说明: 一.基本形式 列表有自己的sort方法,其对列表进行原址排序,既然是原址排序,那显然元组不可能拥有这种方法,因为元组是不 ...

  6. Python中格式化format()方法详解

    Python中格式化format()方法详解 Python中格式化输出字符串使用format()函数, 字符串即类, 可以使用方法; Python是完全面向对象的语言, 任何东西都是对象; 字符串的参 ...

  7. 关于python中的特殊方法

    研究了几个小时,大概对python中的特殊方法一知半解,现在写写自己的理解,以及记录一些找到的资源.待自己有比较深入理解的时候,再来更新 https://docs.python.org/3/refer ...

  8. Python中使用item()方法遍历字典的例子

    Python中使用item()方法遍历字典的例子 这篇文章主要介绍了Python中使用item()方法遍历字典的例子,for...in这种是Python中最常用的遍历字典的方法了,需要的朋友可以参考下 ...

  9. Python中的open()方法总结

    总结Python中的open()方法 message= {'企业即时通信': 'aaa', '企业名称': 'bbb'} with open("..\\r.txt", " ...

随机推荐

  1. .Net Core 程序报错 在上一个操作完成之前,在此上下文上启动了第二个操作。

    错误一: 程序完整报错: A second operation started on this context before a previous operation completed. This ...

  2. CentOS 6 新装服务器部署流程

    1.设置时区 rm -f /etc/localtime cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 2.配置内网IP (如果是外网IP,li ...

  3. VUE 多页面打包webpack配置

      思路:多配置一个main的文件,用于webpack入口使用, 然后路由的导向也应该默认指向新组件,最后通过webpack构建出一个新的独立的html文件. 缺点:生成多个html会new出多个vu ...

  4. EM算法概念

    EM算法是一种非常经典的alternative optimizing算法.alternative optimizing的思想就是对于一个最优化问题,可以计算分为两步或者参数分为两个,就可以随机任意的选 ...

  5. linux中信号的API详解实例

    /************************************************************************* > File Name: signal.c ...

  6. JDBC(连接数据库的四个主要步骤)

    JDBC连接数据库 ?创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.l ...

  7. SpringBoot集成ActiveMq消息队列实现即时和延迟处理

    原文链接:https://blog.csdn.net/My_harbor/article/details/81328727 一.安装ActiveMq 具体安装步骤:自己谷歌去 二.新建springbo ...

  8. Visual Studio 设置为 UTF-8 保存格式

    1. 步骤 Visual Studio 提供高级保存选项功能,它能指定特定代码文件的编码规范和行尾所使用的换行符. 在 VS 中,该命令没有默认显示在「文件」菜单中.用户需要手工设置,才能显示该命令. ...

  9. Python re模块学习

    这是re模块与正则的结合 re模块提供的函数 1.match  尝试在字符串的开头应用该模式,返回匹配对象,如果没有找到匹配,则为None. import re str1 = "Why ar ...

  10. python实战项目 — 爬取中国票房网年度电影信息并保存在csv

    import pandas as pd import requests from bs4 import BeautifulSoup import time def spider(url, header ...