python的高级数组之稀疏矩阵
- 稀疏矩阵的定义:
具有少量非零项的矩阵(在矩阵中,若数值0的元素数目远多于非0元素的数目,并且非0元素分布没有规律时,)则称该矩阵为稀疏矩阵;相反,为稠密矩阵。非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。
稀疏矩阵的两个动机:稀疏矩阵通常具有很大的维度,有时甚大到整个矩阵(零元素)与可用内存不想适应;另一个动机是避免零矩阵元素的运算具有更好的性能。
- 稀疏矩阵的格式
存储矩阵的一般方法是采用二维数组,其优点是可以随机地访问每一个元素,因而能够容易实现矩阵的各种运算。对于稀疏矩阵,采用二维数组的存储方法既浪费大量的存储单元来存放零元素,又要在运算中浪费大量的时间来进行零元素的无效运算。因此必须考虑对稀疏矩阵进行压缩存储(只存储非零元素)。
Scipy.sparse模块提供了许多来自于稀疏矩阵的不同存储格式。这里仅描述最为重要的格式CSR、CSC和LIL。CSR、CSC是用于矩阵-矩阵和矩阵-向量运算的有效格式,LIL格式用于生成和更改稀疏矩阵。Python不能自动创建稀疏矩阵,所以要用scipy中特殊的命令来得到稀疏矩阵。
(1) 压缩稀疏行(CSR,Compressed Sparse Row):或csr_matrix 按行对矩阵进行压缩的。
CSR使用了三个数组,分别为数值、行偏移(表示某一行的第一个元素在数值里面的起始偏移位置,在行偏移的最后补上矩阵总的元素个数)、列号。CSR是一种编码的方式
一维数组data(数值):有序地存储了所有的非零值,它具有与非零元素同样多数量的元素,通常由变量nnz表示。
一维数组indptr(行偏移量):包含了证书使得indptr[i]是data中元素的索引,它是行i中的第一个非零元素。如果整个行i为零,则indptr[i]==indptr[i+1]
如初始矩阵有m行,则len(indptr)==m+1
一维数组Indices(列号:): 其使用如下方式包含列索引信息:indices[indptr[i]:indptr[i+1]]是一个具有行i中非零元素的列索引的整数数组。Len(indice)==len(data)==nnz
备注:列索引表示数值所在的列号,从0开始。
数组data:包含矩阵中的非零元素,以行优先的形式保存。
行偏移:CSR中行索引被压缩,没有行索引,这里用行偏移表示行索引。
实例:
如上图所示:data=(1,7,2,8,5,3,9,6,4)
Indices=(0,1,1,2,0,2,3,1,3) #列索引
Indptr=(0,2,4,7,9) #行偏移(表示某一行的第一个元素在数值里面的起始偏移位置,在行偏移的最后补上矩阵总的元素个数)
在Python中使用:
import numpy as np
from scipy.sparse import csr_matrix
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])
A=csr_matrix((data, indices, indptr), shape=(3, 3)).toarray() #生成CSR格式的矩阵
print(A) #运行结果:
[[1 0 2]
[0 0 3]
[4 5 6]]
解析:第i行的列索引存储在indices[indptr[i]:indptr[i+1]]中,对应的值为data[indptr[i]:indptr[i+1]]。即例如第0行的列索引为indices[0:2]=[0,2](第i行中非零元素的列索引组成的整数数组),值为data[0:2]=[1,2];第1行的列索引为indices[2:3]=[2],值为data[2:3]=[3]…
(2) 稀疏列矩阵CSC(Compressed Sparse Column),用于CSC格式的类型为:csc_matrix 按列对矩阵进行压缩的。
与CSR格式相比唯一的不同点是indptr和indices数组的定义,该定义与列有关。
CSC格式的实例:
import numpy as np
import scipy.sparse as sp
A=np.array([[1,0,2,0],[0,0,0,0],[3,0,0,0],[1,0,0,4]])
AS=sp.csc_matrix(A)
Print(AS)
print(AS.data)
print(AS.indptr)
print(AS.indices)
print(AS.nnz) #运行结果:
[1 3 1 2 4]
[0 3 3 4 5] #注意此处,同一矩阵CSR格式的indptr为[0 2 2 3 5]
[0 2 3 0 3]
5
(3) 基于行的链表格式:LIL(Row-Based Linked List Format)
1. 链表稀疏格式在列表数据中以行方式存储非零元素,
列表data: data[k]是行k中的非零元素的列表。如果该行中的所有元素都为0,则它包含一个空列表。
列表rows: 是在位置k包含了在行k中的非零元素列索引列表。
LIL格式的同一示例:
import numpy as np
import scipy.sparse as sp
A=np.array([[1,0,2,0],[0,0,0,0],[3,0,0,0],[1,0,0,4]])
AS=sp.lil_matrix(A)
print(AS.data)
print(AS.rows)
print(AS.nnz) #运行结果:
[list([1, 2]) list([]) list([3]) list([1, 4])]
[list([0, 2]) list([]) list([0]) list([0, 3])]
5
2. 用LIL格式更改和切割矩阵:
LIL格式最适合切片的方法,即以LIL格式提取子矩阵,并通过插入非零元素来改变稀疏模式。
例如:提取
import numpy as np
import scipy.sparse as sp
A=np.array([[1,0,2,0],[0,0,0,0],[3,0,0,0],[1,0,0,4]])
AS=sp.lil_matrix(A)
print(AS)
BS=AS[0:2,0:3] #切片提取0,1行,0,1,2列组成的子矩阵
print(BS)
print(BS.data)
print(BS.rows)
#运行结果:
(0, 0) 1
(0, 2) 2
[list([1, 2]) list([])]
[list([0, 2]) list([])]
更改:插入新的非零元素会自动更新属性
AS[0,1]=17
print(AS.data)
print(AS.rows)
print(AS.nnz)
#结果: [list([1, 17, 2]) list([]) list([3]) list([1, 4])]
[list([0, 1, 2]) list([]) list([0]) list([0, 3])]
6
- 生成稀疏矩阵:
Numpy包的命令eye、identity、diag和rand都有其对应的稀疏矩阵,这些命令需要额外的参数来指定所得矩阵的稀疏矩阵格式。
import numpy as np
import scipy.sparse as sp
print(sp.eye(20,20,format = 'lil'))
print(sp.spdiags(np.ones((20,)),0,20,20,format = 'csr'))
print(sp.identity(20,format = 'csc'))
print(sp.rand(20,200,density=0.1,format='csr')) #sp.rand命令需要额外的参数来描述生成随机矩阵的密度。
- 稀疏矩阵方法
将稀疏矩阵类型转换为另一种类型和数据或数组的方法:
AS.toarray #转换稀疏矩阵类型为数组
AS.tocsr
AS.tocsc
AS.tolil
#通过issparse、isspmatrix_lil、isspmatrix_csc、isspmatrix_csr等方法检查稀疏矩阵的类型。
import numpy as np
import scipy.sparse as sp
A=np.array([[1,0,2,0],[0,0,0,0],[3,0,0,0],[1,0,0,4]])
def sparse_sin(A):
if not (sp.isspmatrix_csr(A) or sp.isspmatrix_csc(A)):
A=A.tocsr()
A.data=sin(A.data)
return(A)
B=sparse_sin(A)
print(B)
#稀疏矩阵方法的dot,用于矩阵-矩阵或者矩阵-向量乘法运算,返回csr_matrix或Numpy array
例如:import numpy as np
import scipy.sparse as sp
A=np.array([[1,0,2,0],[0,0,0,0],[3,0,0,0],[1,0,0,4]])
AS=sp.csr_matrix(A)
b=np.array([1,2,3,4])
c=AS.dot(b) #结果为:[ 7 0 3 17]
print(c)
c=AS.dot(AS) #结果仍为稀疏矩阵
print(c)
d=np.dot(AS,b)
print(d) #不能返回期望的结果
python的高级数组之稀疏矩阵的更多相关文章
- Python学习之高级数组(一)
1.Python基础学习之高级数组(一) 1.1视图:就是与较大数组共享相同数据的较小数组.Numpy包提供数据视图的概念是为了精确地控制内存的使用方式. 数组视图.切片视图.转置和重塑视图等 数组 ...
- 进击的Python【第五章】:Python的高级应用(二)常用模块
Python的高级应用(二)常用模块学习 本章学习要点: Python模块的定义 time &datetime模块 random模块 os模块 sys模块 shutil模块 ConfigPar ...
- 进击的Python【第四章】:Python的高级应用(一)
Python的高级应用(一) 本章内容: 内置函数 生成器 迭代器 装饰器 JSON和PICKLE的简单用法 软件目录结构规范 一.内置函数 1.数学运算类 abs(x) 求绝对值1.参数可以是整型, ...
- Python Flask高级编程之RESTFul API前后端分离精讲 (网盘免费分享)
Python Flask高级编程之RESTFul API前后端分离精讲 (免费分享) 点击链接或搜索QQ号直接加群获取其它资料: 链接:https://pan.baidu.com/s/12eKrJK ...
- 进击的Python【第七章】:Python的高级应用(四)面向对象编程进阶
Python的高级应用(三)面向对象编程进阶 本章学习要点: 面向对象高级语法部分 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 一.面向对象高级语法部分 静态方法 ...
- 进击的Python【第六章】:Python的高级应用(三)面向对象编程
Python的高级应用(三)面向对象编程 本章学习要点: 面向对象编程介绍 面向对象与面向过程编程的区别 为什么要用面向对象编程思想 面向对象的相关概念 一.面向对象编程介绍 面向对象程序设计(英语: ...
- Python的高级特性8:你真的了解类,对象,实例,方法吗
Python的高级特性1-7系列是本人从Python2过渡3时写下的一些个人见解(不敢说一定对),接下来的系列主要会以类级为主. 类,对象,实例,方法是几个面向对象的几个基本概念,其实我觉得很多人并不 ...
- Python的高级特性7:闭包和装饰器
本节跟第三节关系密切,最好放在一起来看:python的高级特性3:神奇的__call__与返回函数 一.闭包:闭包不好解释,只能先看下面这个例子: In [23]: def outer(part1): ...
- Python:高级主题之(属性取值和赋值过程、属性描述符、装饰器)
Python:高级主题之(属性取值和赋值过程.属性描述符.装饰器) 背景 学习了Javascript才知道原来属性的取值和赋值操作访问的“位置”可能不同.还有词法作用域这个东西,这也是我学习任何一门语 ...
随机推荐
- python 通过js控制滚动条拉取全文 通过psutil获取pid窗口句柄,通过win32gui使程序窗口前置 通过autopy实现右键菜单和另存为操作
1.参考 利用 Python + Selenium 自动化快速截图 利用 Python + Selenium 实现对页面的指定元素截图(可截长图元素) 使用python获取系统所有进程PID以及进程名 ...
- PHP var_dump()函数输出不完整,有省略号?解决办法
xdebug.var_display_max_children=10240xdebug.var_display_max_data=10240xdebug.var_display_max_depth=1 ...
- Docker操作笔记(二)容器
容器 一.启动容器 启动一个容器有两种方式: 1.基于镜像新键并启动一个容器: 所需要的主要命令为docker run docker run ubuntu:18.04 /bin/echo " ...
- java实现单链表反转(倒置)
据说单链表反转问题面试中经常问,而链表这个东西相对于数组的确稍微难想象,因此今天纪录一下单链表反转的代码. 1,先定义一个节点类. 1 public class Node { 2 int index; ...
- webpack之带有可自动打开浏览器及热重载的基本配置
什么是Webpack WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并 ...
- GMA Round 1
学弟说我好久没更blog了. 因为自己最近其实没干什么. 所以来搬运一下GMA Round 1 的比赛内容吧,blog访问量.网站流量一举两得. 链接:https://enceladus.cf/con ...
- react_app 项目开发 (7)_难点集合
/src/App/Admin/Header 布局 import {Row, Col} from "antd" <div className="header_box& ...
- [LeetCode] Letter Case Permutation 字母大小写全排列
Given a string S, we can transform every letter individually to be lowercase or uppercase to create ...
- 转载:[Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
原文:http://www.cnblogs.com/wang-meng/p/5898837.html 一:继承.抽象类与接口区别.访问控制(private, public, protected,默认) ...
- http跳转htts的htaccess文件设置
RewriteEngine OnRewriteCond %{SERVER_PORT} 80RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]Options ...