如何用三元组表表示下列稀疏矩阵_盘一盘 Python 系列特别篇21之:SciPy 稀疏矩阵...

c1218976b981e47717a5261f8e634092.png

引言

和稠密矩阵相比,稀疏矩阵的最大好处就是节省大量的内存空间来储存零。稀疏矩阵本质上还是矩阵,只不过多数位置是空的,那么存储所有的 0 非常浪费。稀疏矩阵的存储机制有很多种 (列出常用的五种):

  • COO (Coordinate List Format):座标格式,容易创建但是不便于矩阵计算,用 coo_matrix

  • CSR (Compressed Sparse Row): 压缩行格式,不容易创建但便于矩阵计算,用 csr_matri

  • CSC (Compressed Sparse Column): 压缩列格式,不容易创建但便于矩阵计算,用 csc_matrix

  • LIL (List of List): 内嵌列表格式,支持切片但也不便于矩阵计算,用 lil_matrix

  • DIA (Diagnoal):对角线格式,适合矩阵计算,用 dia_matrix

在 SciPy 中稀疏矩阵一共有七种,剩余的两种类型 BSR 和 DOK 本贴不做研究。有兴趣的读者可以去官网去查询。

COO

采用三元组 (row, col, data) 的形式来存储矩阵中非零元素的信息,即把非零值 data 按着行坐标 row 和纵坐标 col 写成两个列表。如下图所示:

  • 坐标 (1, 1) 对应的数据 2

  • 坐标 (3, 4) 对应的数据 5

  • 坐标 (0, 2) 对应的数据 9

  • 坐标 (2, 3) 对应的数据 1

  • 坐标 (4, 3) 对应的数据 6

577930edc9ac1813d82bff8f8726540d.gif

在实际使用中,用 coo_matrix() 语法来创建矩阵,注意产出矩阵的格式是COOrdinate。

values = [1, 2, 3, 4]rows = [0, 1, 2, 3]cols = [1, 3, 2, 0]A = sp.coo_matrix((values, (rows, cols)), shape=[4, 4])A
<4x4 sparse matrix of type 'numpy.int32'>'with 4 stored elements in COOrdinate format>

检查矩阵 A 的形状、数据类型、维度和非零值的个数。

A.shape, A.dtype, A.ndim, A.nnz
((4, 4), dtype('int32'), 2, 4)

检查矩阵 A 的行坐标、列坐标和数据。

A.row, A.col, A.data
(array([0, 1, 2, 3], dtype=int32),
 array([1, 3, 2, 0], dtype=int32),
 array([1, 2, 3, 4]))

如果想看 A 中的元素,我们可用 toarray() 转换成 numpy 数组显示出来。

A.toarray()
array([[0, 1, 0, 0],
       [0, 0, 0, 2],
       [0, 0, 3, 0],
       [4, 0, 0, 0]])

COO 矩阵的元素无法进行增删改操作,一般创建成功之后可以转化成其他格式的稀疏矩阵 (如 CSR, CSC) 进行转置、矩阵乘法等操作,或者转成转成 LIL 做切片。

A.tocsr()
<4x4 sparse matrix of type 'numpy.intc'>'with 4 stored elements in Compressed Sparse Row format>
A.tolil()
<4x4 sparse matrix of type 'numpy.intc'>'with 4 stored elements in List of Lists format>

可视化矩阵 A

plt.spy(A);

44245ffb1437a2e1496f063b90b1328c.png

CSR

由三个一维数组 indptrindicesdata 组成。这种格式要求矩阵元按行顺序存储,每一行中的元素可以乱序存储。那么对于每一行就只需要用一个指针表示该行元素的起始位置即可。

  • indices 存储每行中数据的列号,与属性 data 中的元素一一对应

  • indptr 存储每行数据元素的起始位置

如下图所示:

  • 第 1 行:indptr 0-2 指 indices[0:2] 的值即 0 和 2,分别又指第 0 和 2 ,对应的数据 8 和 2

  • 第 2 行:indptr 2-3 指 indices[2:3] 的值即 2,分别又指第 2 ,对应的数据 5

  • 第 3 行:indptr 3-3 指 indices[3:3] 的值为空,无数据

  • 第 4 行:indptr 3-3 指 indices[3:3] 的值为空,无数据

  • 第 5 行:indptr 3-6 指 indices[3:6] 的值即 2,3 和 4,分别又指第 2,3 和 4 ,对应的数据 7,1 和 2

  • 第 6 行:indptr 6-6 指 indices[6:6] 的值为空,无数据

  • 第 7 行:indptr 6-7 指 indices[6:7] 的值即 3,分别又指第 3 ,对应的数据 9

规律:indptr 的长度等于矩阵行数加 1,而第 i 行的列数,就是 indices[indptr[i]:indptr[i+1]]

686244de43fcfa04b498f0da49b8d79e.gif

用 csr_matrix() 语法用来创建矩阵,注意产出矩阵的格式是 Compressed Sparse Row。

data = np.array([1, 2, 3, 4, 5, 6])indices = np.array([0, 2, 2, 0, 1, 2])indptr = np.array([0, 2, 3, 6])A = sp.csr_matrix((data, indices, indptr), shape=(3, 3))A
<3x3 sparse matrix of type 'numpy.int32'>'with 6 stored elements in Compressed Sparse Row format>

检查矩阵 A 的形状、数据类型、维度和非零值的个数。

A.shape, A.dtype, A.ndim, A.nnz
((3, 3), dtype('int32'), 2, 6)

检查矩阵 A 的列索引、索引指针和数据。

A.indices, A.indptr, A.data
(array([0, 2, 2, 0, 1, 2]), array([0, 2, 3, 6]), array([1, 2, 3, 4, 5, 6]))

如果想看 A 中的元素,我们可用 toarray() 转换成 numpy 数组显示出来。

A.toarray()
array([[1, 0, 2],
       [0, 0, 3],
       [4, 5, 6]])

可视化矩阵 A

plt.spy(A);

c3f6ed698ac5d5127165b644bc74f5d7.png

CSC

csc_matrix 和 csr_matrix 正好相反,即按列压缩的稀疏矩阵存储方式,同样由三个一维数组 indptrindicesdata 组成,

  • indices 存储每列中数据的行号,与属性 data 中的元素一一对应

  • indptr 存储每列数据元素的起始位置

如下图所示:

  • 第 0 列:indptr 0-1 指 indices[0:1] 的值即 0,分别又指第 0 ,对应的数据 8

  • 第 1 列:indptr 1-1 指 indices[1:1] 的值为空,无数据

  • 第 2 列:indptr 1-4 指 indices[1:4] 的值即 0,1 和 4,分别又指第 0,1 和 4 ,对应的数据 2,5 和 7

  • 第 3 列:indptr 4-6 指 indices[4:6] 的值即 4 和 6,分别又指第 4 和 6 ,对应的数据 1 和 9

  • 第 4 列:indptr 6-7 指 indices[6:7] 的值即 4,分别又指第 4 ,对应的数据 2

规律:indptr 的长度等于矩阵列数加 1,而第 i 列的行数,就是 indices[indptr[i]:indptr[i+1]]

b30e63b9da871c698db4821652966870.gif

用 csc_matrix() 语法用来创建矩阵,注意产出矩阵的格式是 Compressed Sparse Column。

data = np.array([1, 2, 3, 4, 5, 6])indices = np.array([0, 2, 2, 0, 1, 2])indptr = np.array([0, 2, 3, 6])A = sp.csc_matrix((data, indices, indptr), shape=(3, 3))A
<3x3 sparse matrix of type 'numpy.int32'>'with 6 stored elements in Compressed Sparse Column format>

检查矩阵 A 的形状、数据类型、维度和非零值的个数。

A.shape, A.dtype, A.ndim, A.nnz
((3, 3), dtype('int32'), 2, 6)

检查矩阵 A 的行索引、索引指针和数据。

A.indices, A.indptr, A.data
(array([0, 2, 2, 0, 1, 2]), array([0, 2, 3, 6]), array([1, 2, 3, 4, 5, 6]))

如果想看 A 中的元素,我们可用 toarray() 转换成 numpy 数组显示出来。

A.toarray()
array([[1, 0, 4],
       [0, 0, 5],
       [2, 3, 6]])

可视化矩阵 A

plt.spy(A);

c3f6ed698ac5d5127165b644bc74f5d7.png

LIL

lil_matrix 使用两个嵌套列表存储稀疏矩阵:

  • data 保存每行中的非零元素的值

  • rows 保存每行非零元素所在的列号 (列号是按顺序排的)。

这种格式很适合逐个添加元素,并且能快速获取行相关的数据。如下图所示:

  • 第 0 行:列号为 0,2,4,对应的数据为 8,1,-1

  • 第 1 行:列号为 1,2,对应的数据为 8,2

  • 第 2 行:列号为 2,对应的数据为 3

  • 第 3 行:列号为 0,2,3,4,对应的数据为 -2,4,8,-2

  • 第 4 行:列号为 2,4,对应的数据为 5,8

  • 第 5 行:列号为 2,对应的数据为 6

c84a3e9f5c9f561d535fd90e75cb774e.gif

用 lil_matrix() 语法用来创建矩阵,注意产出矩阵的格式是 Lists of Lists。

data = [[8,0,1,0,-1],        [0,8,2,0,0],        [0,0,3,0,0],        [-2,0,4,8,-2],        [0,0,5,0,8],        [0,0,6,0,0]]A = sp.lil_matrix(data)A
<6x5 sparse matrix of type 'numpy.intc'>'with 13 stored elements in List of Lists format>

检查矩阵 A 的每行的非零值对应的列索引。

A.rows
array([list([0, 2, 4]), list([1, 2]), list([2]), list([0, 2, 3, 4]),
       list([2, 4]), list([2])], dtype=object)

如果想看 A 中的元素,我们可用 toarray() 转换成 numpy 数组显示出来。

A.toarray()
array([[ 8, 0, 1, 0, -1],
       [ 0, 8, 2, 0, 0],
       [ 0, 0, 3, 0, 0],
       [-2, 0, 4, 8, -2],
       [ 0, 0, 5, 0, 8],
       [ 0, 0, 6, 0, 0]], dtype=int32)

可视化矩阵 A

plt.spy(A);

f6ca56a7d9d6b2974786fba008bd00f9.png

DIA

dia_matrix 按对角线的存储方式。稀疏矩阵使用 offsets 和 data 两个矩阵来表示,其中offsets 表示 data 中每一行数据在原始稀疏矩阵中的对角线位置 k:

  • k > 0, 对角线往右上方移动 k 个单位

  • k < 0, 对角线往左下方移动 k 个单位

  • k = 0,主对角线

如下图所示:

  • offset 0 对应的数据 [1,2,3,4,5] 在主对角线上

  • offset -3 对应的数据 [6,7,8,9,10] 在主对角线左下方移动 3 个单位

  • offset 2 对应的数据 [11,12,13,14,15] 在对角线上右上方移动 2 个单位

5068adcaa17ea49d727bd6f4c33b9582.gif

用 dia_matrix() 语法用来创建矩阵,注意产出矩阵的格式是 DIAgonal。

data = np.arange(1,13).reshape(3,-1)offset = [-1, 0, 1]A = sp.dia_matrix( (data, offset), shape=(4,4) )A
<4x4 sparse matrix of type 'numpy.int32'>'with 10 stored elements (3 diagonals) in DIAgonal format>

检查矩阵 A 的平移单位。

A.offsets
array([-1, 0, 1], dtype=int32)

如果想看 A 中的元素,我们可用 toarray() 转换成 numpy 数组显示出来。

A.toarray()
array([[ 5, 10, 0, 0],
       [ 1, 6, 11, 0],
       [ 0, 2, 7, 12],
       [ 0, 0, 3, 8]])

可视化矩阵 A

plt.spy(A);

38da43b1ee4e8c669d4195dda2674cb8.png

此外,在 sp.sparse 模块里还有一些直接创建稀疏矩阵的函数:

  • eye 生成稀疏单位对角阵

  • diags 构建稀疏对角阵

  • spdiags 构建稀疏对角阵

假设我们想生成一个方阵,主对角线上面是 -2,上下次对角线上的值为 1。

方法一:用 eye

N = 5A = sp.eye(N, k=1) - 2 * sp.eye(N) + sp.eye(N, k=-1)A.toarray()
array([[-2., 1., 0., 0., 0.],
       [ 1., -2., 1., 0., 0.],
       [ 0., 1., -2., 1., 0.],
       [ 0., 0., 1., -2., 1.],
       [ 0., 0., 0., 1., -2.]])

方法二:用 diags

A = sp.diags([1, -2, 1], [1, 0, -1], (N, N), format='csc')A.toarray()
array([[-2., 1., 0., 0., 0.],
       [ 1., -2., 1., 0., 0.],
       [ 0., 1., -2., 1., 0.],
       [ 0., 0., 1., -2., 1.],
       [ 0., 0., 0., 1., -2.]])

方法三:用 spdiags

data = np.vstack( [np.repeat(1,N), np.repeat(-2,N), np.repeat(1,N)] )A = sp.spdiags( data, [1, 0, -1], N, N )A.toarray()
array([[-2., 1., 0., 0., 0.],
       [ 1., -2., 1., 0., 0.],
       [ 0., 1., -2., 1., 0.],
       [ 0., 0., 1., -2., 1.],
       [ 0., 0., 0., 1., -2.]])

三种方法都得到一样的结果,但是用  diags 方法代码最简洁些。但是如果对角线上的值都不一样,那么只能用 spdiags 方法,原因是它的参数是数组,而不是元素。

在金工中一维 PDE 有限差分离散之后都是这种类型的三对角矩阵 (tri-diagnol),因此要熟练掌握用 diags/spdiags 方法来创建金工需要的“稀疏矩阵”。

总结

从官网资料看出,一般使用 lil_matrix 来构建矩阵效率最高。由于 LIL 形式是基于行的,因此它能够很高效的转为 CSR,但是转为 CSC 的效率相对较低。

如果要执行矩阵乘法或转置,将它们转换成 CSC 或 CSR 格式,效率最高。

总之,在运算稀疏矩阵时,绝对绝对不要直接使用 NumPy!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

如果觉得好,关注、转发、在看三连发走起  666~~~

福利来一波~~~

关注公众号回复以下信息送免费资料
回复Jenkins 领取Jenkins学习资料回复Jmeter 领取Jmeter学习资料

回复Java   领取Java学习资料

回复Python 领取python入门资料

回复RobotFramework   领取RobotFramework 框架搭建资料

69c6a4fa9f363cd628a22713b92db36d.png

你可能会喜欢

  • Jmeter关联系列_数据驱动中的业务逻辑关联

  • docker搭建接口自动化持续集成框架

  • python28:迷宫游戏最短路径算法

  • 4300 字Python列表使用总结,用心!

  • 盘一盘 Python 系列基础篇十一之 机器学习 Sklearn

  • 盘一盘 Python 系列特别篇二十之 天数计数|年限

  • Linux环境部署之ubuntu网络配置

  • 性能测试指标7:性能测试的阶段性工作

  • jmeter之对jar包进行调用

  • jmeter之爬取网络图片

  • 软件质量保障体系图

  • 研发过程中的测试工作

  • APP测试流程及测试点

  • WEB测试范围小结

测试交流,加我备注【测试交流】拉入交流群,更有不定期资料赠送,敬请期待

6872b2516126d6dd383d2724cef9ddd6.png

本文转载自【公众号:王的机器

83d1536eaafd21fc79b9d4a99ef37211.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/504035.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

六西格玛dfss_向六西格玛质量水平进攻!

为提高设计质量&#xff0c;提升研发团队整体作战能力&#xff0c;2019年初&#xff0c;技术中心确定了大力推进先进质量管理方法DFSS(六西格玛设计)的工作目标。一年来&#xff0c;在DFSS小组的策划组织和通用黑带大师的倾力支持下 &#xff0c;技术中心各区域工程师积极地学习…

c字符串中包含双引号_必须知道的C语言知识细节:单引号和双引号正确用法

C语言中ACSII码字符单引号和双引号"在程序中经常出现&#xff0c;很简单&#xff0c;但却是十分重要的语法标点符号&#xff0c;初学者容易混淆使用。单引号在字符常量时使用&#xff0c;表示单个字符。例如&#xff1a;char c;c a;c 1;c A;当在单引号中出现两个及以上…

计算机组成原理哈工大期末_浅谈计算机组成原理(三)

1、第二章&#xff1a;存储系统通过下面的思维导图来依次分享「存储系统」里面重要知识点。2、第一节&#xff1a;存储器的结构1. 主存储器&#xff1a;简称主存&#xff0c;又称内存储器(内存)&#xff0c;用来存放计算机运行期间所需的大量程序和数据&#xff0c;CPU可以直接…

网页中竖的目录怎么改成横的_怎么学习手绘插画?小白也能入门哦

怎么学习手绘插画&#xff1f;小白也能入门哦&#xff01;在回答这个问题之前&#xff0c;我们先来认识一下什么插画&#xff1f;相信很多人对插画这个概念是很笼统的。插画在中国被人们俗称为插图。发展至今其应用范围很是广泛包括&#xff1b;出版物配图、卡通吉祥物、广告、…

python自动测试v_python下selenium自动化测试自我实践

周末实验自动化提交数据时&#xff0c;本来没打算写记录的&#xff0c;不过遇到一些问题&#xff0c;觉得可以提提。基本操作就不用写了&#xff0c;搜索过程中都发现了两个博客都出了seleniumpython的书&#xff0c;说明操作一搜一大把。 1. 等待页面加载完成 本来用的sleep()…

graphpad细胞增殖曲线_肿瘤干细胞?居然被这两个新加坡人轻松干掉了?

近日&#xff0c;著名医学期刊《自然•医学》上发表了一篇关于肿瘤干细胞的文章。来自新加坡的研究团队发现&#xff0c;人类非小细胞肺癌的肿瘤干细胞需要大量的蛋氨酸&#xff0c;以维持自身组蛋白的甲基化&#xff0c;这对于肿瘤干细胞的生长和致瘤作用至关重要。同时&#…

isight参数优化理论与实例详解_案例1(ISIGHT集成ADAMS CAR方法实现)

本文字数1304字25图&#xff0c;建议阅读时间7分钟强调一下是ISIGHT&#xff0c;不是INSIGHTINSIGHT是ADAMS内置的一个试验设计模块&#xff0c;它提供了一组统计工具&#xff0c;用于分析仿真结果&#xff0c;辅助优化和改进系统ISIGHT是功能强大的计算机辅助优化平台&#xf…

修改图片src_【学习园地】企业SRC搭建

xSRC-企业SRC搭建腾讯xSRC 开源版是腾讯安全应急响应中心(TSRC)面向合作伙伴推出的安全应急响应中心(SRC)建站软件&#xff0c;软件源代码开放&#xff0c;可支持合作伙伴轻松构建SRC平台&#xff0c;省去大量开发运维工作&#xff0c;并支持个性化功能及页面设置&#xff0c;企…

2 数据源配置_论多数据源(读写分离)的实现方案

好的&#xff0c;作为一个合格的bug生产者&#xff0c;我们直接进入主题&#xff0c;多数据源和读写分离实现方案。首先多数据源和读写分离什么时候我们才需要呢&#xff1f;多数据源&#xff1a;一个单体项目过于复杂&#xff0c;需要操作多个业务库的时候&#xff0c;就需要多…

docker安装gitlab_docker 安装部署gitlab

下载镜像并且启动//下载镜像(镜像较大,如果网速不行可以切换阿里云镜像仓库) docker pull gitlab/gitlab-ce&#xff1a;latest //启动镜像 docker run --name gitlab -d -p 18080:80 -p 1443:443 -p 2222:22 -v /data/gitlab/config:/etc/gitlab -v /data/gitlab/logs:/var/lo…

easyexcel导出百万级数据_百万级别数据Excel导出优化

这篇文章不是标题党&#xff0c;下文会通过一个仿真例子分析如何优化百万级别数据Excel导出。笔者负责维护的一个数据查询和数据导出服务是一个相对远古的单点应用&#xff0c;在上一次云迁移之后扩展为双节点部署&#xff0c;但是发现了服务经常因为大数据量的数据导出频繁Ful…

运行catia_CATIA清除错误目录及防串链接

清除错误目录大家好今天我来教大家如何清除CATIA错误目录&#xff0c;由于我们在日常工作中经常会互相发送数据&#xff0c;而CATIA的缓存功能通常会记录这些文件的路径&#xff0c;所以我们打开别人发的数据时在桌面的右下角通常会有警告的提醒&#xff0c;那我们如何来清除缓…

python 键盘输入数字_九宫格键盘输入

九宫格键盘输入 Letter Combinations of a Phone Number 给定一个数字字符串&#xff0c;返回数字可能代表的所有可能的字母组合。 数字到字母的映射&#xff08;就像九宫格电话按钮一样&#xff09;如下图。 Given a digit string, return all possible letter combinations t…

java2组随机数的共通数_java随机数产生-指数分布 正态分布 等

1 指数分布指数分布的概率密度函数&#xff1a;ylamda*exp(-lamda*x)x>0由此可以计算概率分布函数&#xff1a;y1-exp(-lamda*x)x>0y是 X首先&#xff0c;把y当作是在(0&#xff0c;1)区间的均匀分布的随机变量。然后&#xff0c;求y1-exp(-lamda*x)的逆函数&#xff0c…

c# combobox集合数据不显示_excel打开数据时显示乱码/问号amp;看起来一样却v不出来怎么办...

1、乱码问题&#xff1a;今天正好碰到这种情况&#xff0c;想起来写一写。有时从客户那里拿到的CSV等文件&#xff0c;直接用excel打开是这样的&#xff1a;其实观察一下会发现&#xff1f;的地方一般就是中文&#xff0c;实质上是中文字符显示不出来。有小伙伴一直是单独下个W…

if嵌套while循环语句_Python学习笔记015--while循环嵌套

while循环嵌套前面学习过if的嵌套了&#xff0c;想一想if嵌套是什么样子的&#xff1f;类似if的嵌套&#xff0c;while嵌套就是&#xff1a;while里面还有while<1>while嵌套的格式while 条件1:条件1满足时&#xff0c;做的事情1条件1满足时&#xff0c;做的事情2条件1满足…

long类型怎么转换成string_Python知识点-Python变量类型有哪些?

Python的内置变量类型是非常基础的知识点&#xff0c;善用变量类型转换在日常的工作学习中会给我们带来非常大的帮助。相对于其他语言&#xff0c;Python的变量类型既有自己的特色方法&#xff0c;也有借鉴前辈的优秀之处。今天酷仔整理总结了关于Python内置变量类型一文&#…

mysql连接服务密码_Hydra爆破常见服务密码

Hydra是一款专业的服务密码探测工具&#xff0c;支持FTP、LDAP、MYSQL、Oracle、POP3、SMB、SSH等网络服务&#xff0c;多用于信息安全检查工作中弱口令登陆测试。实验环境操作系统&#xff1a;Kali 2019.4目标网络&#xff1a;192.168.168.0/24爆破教程第一步 升级系统、软件版…

矩阵求逆c语言实现_[V-SLAM] Bundle Adjustment 实现

SLAM问题的后端有主要有滤波和优化两种方案。目前&#xff0c;普遍认为优化的方法在精度上要超过滤波方法&#xff0c;因为它可以进行多次的线性化。近年来出现的SLAM算法也大都是基于优化的算法&#xff08;如ORB-SLAM、DSO等&#xff09;。优化问题的核心便是Bundle Adjustme…

centos安装 mysql_Linux centos 安装 mysql 5.6

一、mysql下载1、方式一(简单粗暴)直接在linux 目录下wget https://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.43-linux-glibc2.12-x86_64.tar.gz2、方式二(官方下载)浏览器打开网址&#xff1a;https://www.mysql.com如下图依次点击1、2、3、4步如下图设置对应版本点击…