我正在使用大型稀疏二进制矩阵.我使用Scipy稀疏矩阵实现来压缩它们.从scipy.spatial.distance计算Jaccard距离不支持对稀疏矩阵的直接操作,因此:

>将整个稀疏矩阵转换为密集,然后在每一行上作为内存饥饿的向量进行操作

要么

>遍历稀疏,使用getrow()抓住每一行并运行.

要么

>编写我们自己的实现来处理稀疏矩阵.

为了正确看待,这里是示例代码:

import scipy.spatial.distance as d

import numpy as np

from scipy.sparse import csr_matrix

# benchmark performance

X = np.random.random((3000, 3000))

# binarize

X[X > 0.3] = 0

X[X>0] = 1

mat = csr_matrix(X)

a = np.zeros(3000)

a[4] = a[100] = a[22] =1

a = csr_matrix(a)

def jaccard_fast(v1,v2):

common = v1.dot(v2.T)

dis = (v1 != v2).getnnz()

if common[0,0]:

return 1.0-float(common[0,0])/float(common[0,0]+dis)

else:

return 0.0

def benchmark_jaccard_fast():

for i in range(mat.shape[0]):

jaccard_fast(mat.getrow(i),a)

def benchmark_jaccard_internal_todense():

for v1,v2 in zip(mat.todense(),a.todense()):

d.jaccard(v1,v2)

def benchmark_jaccard_internal_getrow():

for i in range(mat.shape[0]):

d.jaccard(mat.getrow(i),a)

print "Jaccard Fast:"

%time benchmark_jaccard_fast()

print "Jaccard Scipy (expanding to dense):"

%time benchmark_jaccard_internal_todense()

print "Jaccard Scipy (using getrow):"

%time benchmark_jaccard_internal_getrow()

其中jaccard_fast是我自己的实现.看起来我的实现比scipy稀疏矩阵上的内部更快,但是getrow()似乎会减慢我的实现速度.当我对scipy.spatial.distance.jaccard对jaccard_fast进行基准测试时,结果如下:

Jaccard Fast:

CPU times: user 1.28 s, sys: 0 ns, total: 1.28 s

Wall time: 1.28 s

Jaccard Scipy (expanding to dense):

CPU times: user 28 ms, sys: 8 ms, total: 36 ms

Wall time: 37.2 ms

Jaccard Scipy (using getrow):

CPU times: user 1.82 s, sys: 0 ns, total: 1.82 s

Wall time: 1.81 s

任何有关如何避免getrow瓶颈的帮助将不胜感激.由于内存限制,我无法使用todense()扩展我的稀疏矩阵.

解决方法:

In [33]: timeit for row in mat: x=row # sparse iteration

1 loops, best of 3: 510 ms per loop

In [35]: timeit for row in mat.todense(): x=row # dense iteration

10 loops, best of 3: 175 ms per loop

但我发现使用稀疏矩阵时你的d.jacard也会变慢

In [36]: ad=a.todense()

In [37]: timeit for row in mat.todense(): d.jaccard(row,ad) # all dense

1 loops, best of 3: 734 ms per loop

In [38]: timeit for row in mat: d.jaccard(row.todense(),ad) # inner dense

1 loops, best of 3: 1.69 s per loop

In [39]: timeit for row in mat: d.jaccard(row,a) # all sparse

1 loops, best of 3: 4.61 s per loop

消除地理因素

In [40]: mrow=mat.getrow(0)

In [41]: mrowd=mrow.todense()

In [42]: timeit d.jaccard(mrow, a) # one sparse row

1000 loops, best of 3: 1.32 ms per loop

In [43]: timeit d.jaccard(mrow.todense(), a.todense()) # with conversion

1000 loops, best of 3: 539 µs per loop

In [44]: timeit d.jaccard(mrowd, ad) # dense

10000 loops, best of 3: 173 µs per loop

======================

我需要重新运行这些测试,因为d.jaccard不能用于稀疏(并且jaccard_fast不能用于密集).因此,将稀疏行迭代问题与jaccard计算分开将需要更多工作.

我重写了jaccard_fast:

def my_jaccard(mat, a):

common = mat*a.T # sparse does the large matrix product well

dis=np.array([(row!=a).getnnz() for row in mat]) # iterative

cA = common.A.ravel()

return 1 - cA/(cA + dis)

它返回与密集行上运行的d.jaccard匹配的值.对于common为0的行,d.jaccard返回1.我似乎不需要cA测试(除非cA和dis在同一个插槽中都可能为0).

In [141]: r=np.array([d.jaccard(row,ad) for row in mat.todense()])

In [142]: r1=my_jaccard(mat,a)

In [143]: np.allclose(r,r1)

Out[143]: True

速度只有一半.如果我可以返工,那么dis calc应该具有相似的速度.

In [144]: timeit r=np.array([d.jaccard(row,ad) for row in mat.todense()])

1 loops, best of 3: 783 ms per loop

In [145]: timeit r1=my_jaccard(mat,a)

1 loops, best of 3: 1.29 s per loop

进一步调整计算结果.我屏蔽了0的常用值.这有两个目的 – 它确保我们没有除以0的问题,并且它减少了迭代次数,从而提高了速度.

def my_jaccard(mat, a):

common=mat*a.T

cA = common.A.ravel()

mask = cA!=0

cA = cA[mask]

dis = np.array([(row!=a).getnnz() for row, b in zip(mat,mask) if b])

ret = np.ones(mat.shape[0])

ret[mask] = 1 - cA/(cA+dis)

return ret

有了这个,时间有点下降.

In [188]: timeit my_jaccard(mat,a)

1 loops, best of 3: 1.04 s per loop

==================

在那个问题中,我研究了将稀疏矩阵与1行矩阵进行比较,并发现使用sparse.kron来复制行,是复制numpy广播的最快方法.

在jaccard中使用该想法来计算dis数组

def my_jaccard1(mat, a):

common = mat*a.T

cA = common.A.ravel()

aM = sparse.kron(a,np.ones((mat.shape[0],1),int))

dis = (mat!=aM).sum(1)

ret = 1-cA/(cA+dis.A1)

return ret

随着这个时间显着改善(10倍):

In [318]: timeit my_jaccard1(mat,a)

1 loops, best of 3: 97.1 ms per loop

我可以像以前一样应用掩蔽来防止零除;但它实际上减慢了计算速度(到140ms).

def my_jaccard3(mat, a):

common = mat*a.T

cA = common.A.ravel()

mask = cA!=0

cA = cA[mask]

aM = sparse.kron(a,np.ones((len(cA),1),int))

dis = (mat[mask,:]!=aM).sum(1)

ret = np.ones(mat.shape[0])

ret[mask] = 1 - cA/(cA+dis.A1)

return ret

========================

编辑 – 测试疑似病例

In [75]: x,y= np.array([1,1,0,0,1,0]), np.array([0,0,1,0,1,0])

In [76]: d.jaccard(x,y)

Out[76]: 0.75

In [78]: jaccard_fast(sparse.csr_matrix(x),sparse.csr_matrix(y))

Out[78]: 0.75

我的版本:

In [79]: my_jaccard(sparse.csr_matrix(x),sparse.csr_matrix(y))

Out[79]: array([ 0.75])

...

In [82]: my_jaccard3(sparse.csr_matrix(x),sparse.csr_matrix(y))

Out[82]: array([ 0.75])

(编辑 – 显式使用sparse.kron)

标签:python,scipy,sparse-matrix

来源: https://codeday.me/bug/20190628/1311561.html

python row_python – 用于getrow的Scipy稀疏矩阵替代()相关推荐

  1. 不是python中用于开发用户界面的第三方库-模拟试卷C

    原标题:模拟试卷C 一.单项选择题 1. 按照"后进先出"原则组织数据的数据结构是____ 队列 栈 双向链表 二叉树 2. 以下选项的叙述中,正确的是 循环队列有队头和队尾两个指 ...

  2. 【Python】Windows下安装scipy库步骤

    概述 由于学习需要,需要安装scipy库.scipy库在Windows下使用pip安装失败,所以需要寻找安装包进行安装,下面是记录步骤. 开发环境 win10 x64 Python 3.5.1 安装s ...

  3. python中用于释放类占用的资源的方法是()_mooc大学英语词汇期末答案

    把两个已有项目放到一起,就是一个新项目,这种项目来源属于(?? ) 答:整合 辩证法同形而上学的斗争 答:是从属于唯物主义同唯心主义的斗争,并同这种斗争交织在一起的 中国大学MOOC: 广义的计划是对 ...

  4. python3.7安装numpy库和matplotlib库_详解Python中的Numpy、SciPy、MatPlotLib安装与配置

    用Python来编写机器学习方面的代码是相当简单的,因为Python下有很多关于机器学习的库.其中下面三个库numpy,scipy,matplotlib,scikit-learn是常用组合,分别是科学 ...

  5. Python中用于判断两个集合的交集是否为空集isdisjoint()方法

    [小白从小学Python.C.Java] [Python全国计算机等级考试] [Python数据分析考试必会题] ​● 标题与摘要 Python中用于判断两个集合的交集是否为空集 isdisjoint ...

  6. SciPy稀疏矩阵类 scipy.sparse(持续更新ing...)

    诸神缄默不语-个人CSDN博文目录 scipy官方文档:SciPy documentation - SciPy v1.9.0 Manual scipy.sparse官方文档:Sparse matric ...

  7. Python中用于计算对数的log()方法

    本文转载至:http://www.jb51.net/article/66130.htm 这篇文章主要介绍了Python中用于计算对数的log()方法,是Python入门基础中的必会的方法,需要的朋友可 ...

  8. python报错AttributeError module ‘scipy.misc‘ has no attribute ‘imresize‘和 ‘imread‘

    python报错AttributeError: module 'scipy.misc' has no attribute 'imresize'和 'imread' 报错原因:scipy版本过高 解决方 ...

  9. 想了解Python中用于图像处理的OpenCV基础知识吗?

    导语 OpenCV称为开源计算机视觉,是Python中用于计算机视觉和图像处理任务的库. 它有一个模块化的结构,包括几个共享的和静态的库.OpenCV可以应用于Python.C++.Java等语言中. ...

  10. python中用于释放类占用的资源的方法是()_编写一个简易计算器,要求根据输入的数字和四则运算符号,计算运算结果并输出。_学小易找答案...

    [简答题]20191220 课前作业 新工作页4.1的3-5-3页的填空题,参考教材P135-P144 [简答题]AutoCAD改编视图,尽量不用虚线 1. 主视图采用局部剖,表达右上角小圆筒(及孔) ...

最新文章

  1. 服务器数据恢复难题--操作系统恢复的方法和思路
  2. 几张旧照片,用傻瓜拍的,翻出来凑数 (续)
  3. android listview 滑动条显示_第七十六回:Android中UI控件之RecyclerView基础
  4. Google 6面,最终还是挂了…
  5. 7-2 简单计算器 (13 分)
  6. CGCS2000大地坐标系、北斗坐标系(BDCS)与WGS84坐标系的差异
  7. 末日帝国——Agile公司的困境 (4)
  8. 电脑锁屏按什么键解锁_锁屏键除了锁屏还能干什么?这 6 个 App 带你玩转手机实体键...
  9. thinkphp 下载txt文档
  10. 期刊论文格式是什么样的,如何排版?
  11. 华为U2000云平台和APP管理系统建设
  12. 蔡氏电路matlab,基于MATLABSimulink的蔡氏电路研究(Simulink搭建仿真系统)
  13. (自兴人工智能)python元组
  14. Q4财报发布,腾讯音乐高质量增长背后的创新进化论
  15. AI实战:目标检测模型应用之生活垃圾图片分类
  16. JavaWeb程序设计课后答案
  17. win10安装消息队列服务器,win10下celery搭建使用
  18. QPainter实现简单的绘图程序(绘图工具)
  19. 应公司需要,开发了一个CPU卡的发卡工具
  20. 数字图像处理之特征提取及常用方法

热门文章

  1. 裸辞两个月,海投一个月,从 Android 转战 Web 前端的求职之路
  2. JDF bean模块想法交流
  3. linux网络操作系统项目教程第三版答案,《Linux网络操作系统项目教程(RHEL7.4 CentOS 7.4)(第3版))》习题及答案...
  4. 通过关键词获取微博内容
  5. CT图像的窗宽窗位(VTK及3Dslicer中的使用)
  6. 解压RAR时出现“不可预料的压缩文件末端”的解决方法
  7. oracle虚拟用户和密码,创建 Virtual Private Catalog(虚拟用户目录)(Oracle 11g)
  8. Java实现对png图片文件电子签名操作
  9. NYOJ 366 (全排列)
  10. 编译原理: Thompson 构造法(正则表达式 转 NFA)