为什么 scipy csr 矩阵的行索引比 numpy 数组慢

2023-12-04

我不确定我做错了什么,但似乎行索引 scipycsr_matrix与 numpy 数组相比,速度大约慢 2 倍(参见下面的代码)。

csr 矩阵的行索引不应该比密集矩阵更快吗,因为只提取很少的非零元素,如下例所示?

是否有技巧可以使 scipy csr 矩阵的行索引更快?

import numpy as np
import timeit
from scipy.sparse import csr_matrix

# Generate random matrix
A = np.random.rand(5000, 1000)

# Make A sparse
A[:, 4:] =0

# Create sparse matrix
A_sparse = csr_matrix(A)

# Create row indexing functions
def index_A_dense():
    A[4]

def index_A_dense_copy():
    a = A[4].copy()

def index_A_sparse():
    A_sparse[4]

timeit.timeit(index_A_sparse, number=10000)
Out: 0.6668063667304978
timeit.timeit(index_A_dense, number=10000)
Out: 0.0029007720424942818
timeit.timeit(index_A_dense_copy, number=10000)
Out: 0.00979283193282754

提前致谢!


我在下面演示的简短答案是构建新的稀疏矩阵的成本很高。存在很大的开销,该开销不依赖于行数或特定行中非零元素的数量。


稀疏矩阵的数据表示与稠密数组的数据表示有很大不同。数组将数据存储在一一连续的缓冲区中,并有效地使用shape and strides迭代选定的值。这些值加上索引,精确定义了它将在缓冲区中找到的数据。复制那些N从一个位置到另一个位置的字节是整个操作中相对较小的部分。

稀疏矩阵将数据存储在多个数组(或其他结构)中,包含索引和数据。然后选择一行需要查找相关索引,并使用选定的索引和数据构造一个新的稀疏矩阵。稀疏包中有已编译的代码,但底层代码并不像 numpy 数组那么多。

为了说明这一点,我将制作一个小矩阵,并且不是那么密集,因此我们没有很多空行:

In [259]: A = (sparse.rand(5,5,.4,'csr')*20).floor()
In [260]: A
Out[260]: 
<5x5 sparse matrix of type '<class 'numpy.float64'>'
    with 10 stored elements in Compressed Sparse Row format>

密集等价物和行副本:

In [262]: Ad=A.A
In [263]: Ad
Out[263]: 
array([[  0.,   0.,   0.,   0.,  10.],
       [  0.,   0.,   0.,   0.,   0.],
       [ 17.,  16.,  14.,  19.,   6.],
       [  0.,   0.,   1.,   0.,   0.],
       [ 14.,   0.,   9.,   0.,   0.]])
In [264]: Ad[4,:]
Out[264]: array([ 14.,   0.,   9.,   0.,   0.])
In [265]: timeit Ad[4,:].copy()
100000 loops, best of 3: 4.58 µs per loop

矩阵行:

In [266]: A[4,:]
Out[266]: 
<1x5 sparse matrix of type '<class 'numpy.float64'>'
    with 2 stored elements in Compressed Sparse Row format>

看看这个的数据表示csr矩阵,3 个一维数组:

In [267]: A.data
Out[267]: array([  0.,  10.,  17.,  16.,  14.,  19.,   6.,   1.,  14.,   9.])  
In [268]: A.indices
Out[268]: array([3, 4, 0, 1, 2, 3, 4, 2, 0, 2], dtype=int32)
In [269]: A.indptr
Out[269]: array([ 0,  2,  2,  7,  8, 10], dtype=int32)

以下是选择行的方式(但在编译代码中):

In [270]: A.indices[A.indptr[4]:A.indptr[5]]
Out[270]: array([0, 2], dtype=int32)
In [271]: A.data[A.indptr[4]:A.indptr[5]]
Out[271]: array([ 14.,   9.])

“行”是另一个稀疏矩阵,具有相同类型的数据数组:

In [272]: A[4,:].indptr
Out[272]: array([0, 2])
In [273]: A[4,:].indices
Out[273]: array([0, 2])
In [274]: timeit A[4,:]

是的,稀疏矩阵的计时很慢。我不知道实际选择数据花费了多少时间,以及构建新矩阵花费了多少时间。

10000 loops, best of 3: 145 µs per loop
In [275]: timeit Ad[4,:].copy()
100000 loops, best of 3: 4.56 µs per loop

lil格式可能更容易理解,因为数据和索引存储在子列表中,每行一个。

In [276]: Al=A.tolil()
In [277]: Al.data
Out[277]: array([[0.0, 10.0], [], [17.0, 16.0, 14.0, 19.0, 6.0], [1.0], [14.0, 9.0]], dtype=object)
In [278]: Al.rows
Out[278]: array([[3, 4], [], [0, 1, 2, 3, 4], [2], [0, 2]], dtype=object)
In [279]: Al[4,:].data
Out[279]: array([[14.0, 9.0]], dtype=object)
In [280]: Al[4,:].rows
Out[280]: array([[0, 2]], dtype=object)

在处理紧密编译的代码时,这样的速度比较是有意义的,其中字节从内存的一部分到另一部分的移动会消耗大量时间。将 Python 和编译代码混合在一起numpy and scipy你不能只数数O(n)运营。

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

以下是从中选择一行所需的时间估计A,以及返回新的稀疏矩阵所需的时间:

只需获取数据:

In [292]: %%timeit
d1=A.data[A.indptr[4]:A.indptr[5]]
i1=A.indices[A.indptr[4]:A.indptr[5]]
   .....: 
100000 loops, best of 3: 4.92 µs per loop

加上制作矩阵所需的时间:

In [293]: %%timeit
d1=A.data[A.indptr[4]:A.indptr[5]]
i1=A.indices[A.indptr[4]:A.indptr[5]]
sparse.csr_matrix((d1,([0,0],i1)),shape=(1,5))
   .....: 
1000 loops, best of 3: 445 µs per loop

尝试更简单的coo matrix

In [294]: %%timeit
d1=A.data[A.indptr[4]:A.indptr[5]]
i1=A.indices[A.indptr[4]:A.indptr[5]]
sparse.coo_matrix((d1,([0,0],i1)),shape=(1,5))
   .....: 
10000 loops, best of 3: 135 µs per loop
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 scipy csr 矩阵的行索引比 numpy 数组慢 的相关文章

  • 替换字符串列表中的 \x00 的最佳方法?

    我有一个来自已解析 PE 文件的值列表 其中包括 x00每个部分末尾的空字节 我希望能够删除 x00字符串中的字节而不删除所有字节 x 文件中的 s 我试过做 replace and re sub 但并没有取得太大成功 使用Python 2
  • 如何在 Ubuntu 上安装 Python 模块

    我刚刚用Python写了一个函数 然后 我想将其做成模块并安装在我的 Ubuntu 11 04 上 这就是我所做的 创建 setup py 和 function py 文件 使用 Python2 7 setup py sdist 构建分发文
  • Python 中的六边形自组织映射

    我在寻找六边形 自组织映射 http en wikipedia org wiki Self organizing map在Python上 准备好模块 如果存在的话 绘制六边形单元格的方法 将六边形单元作为数组或其他方式使用的算法 About
  • 获取单个方程的脚本

    在文本文件中输入 a 2 8 b 3 9 c 4 8 d 5 9 e a b f c d g 0 6 h 1 7 i e g j f h output i j 期望的输出 输出 2 8 3 9 0 6 4 8 5 9 1 7 如果输入文件名
  • 如何自动替换多个文件的文本内容中的字符?

    我有一个文件夹 myfolder包含许多乳胶表 我需要替换其中每个字符 即替换任何minus sign by an en dash 只是为了确定 我们正在替换连字符INSIDE该文件夹中的所有 tex 文件 我不关心 tex 文件名 手动执
  • NLTK、搭配问题:需要解包的值太多(预期为 2)

    我尝试使用 NLTK 检索搭配 但出现错误 我使用内置的古腾堡语料库 I wrote alice nltk corpus gutenberg fileids 7 al nltk corpus gutenberg words alice al
  • Python 中 genfromtxt() 的可变列数?

    我有一个 txt具有不同长度的行的文件 每一行都是代表一条轨迹的一系列点 由于每条轨迹都有自己的长度 因此各行的长度都不同 也就是说 列数从一行到另一行不同 据我所知 genfromtxt Python 中的模块要求列数相同 gt gt g
  • 使用正则表达式解析 Snort 警报文件

    我正在尝试使用 Python 中的正则表达式从 snort 警报文件中解析出源 目标 IP 和端口 和时间戳 示例如下 03 09 14 10 43 323717 1 2008015 9 ET MALWARE User Agent Win9
  • 行为:如何从另一个文件导入步骤?

    我刚刚开始使用behave http pythonhosted org behave 一个Pythonic BDD框架 使用小黄瓜语法 http docs behat org guides 1 gherkin html 行为需要一个特征 例
  • 如何为多组精灵创建随机位置?

    我尝试使用 blit 和 draw 方法进行 for 循环 并为 PlayerSprite 和 Treegroup 使用不同的变量 for PlayerSprite in Treegroup surface blit PlayerSprit
  • Pandas:根据列名进行列的成对乘法

    我有以下数据框 gt gt gt df pd DataFrame ap1 X 1 2 3 4 as1 X 1 2 3 4 ap2 X 2 2 2 2 as2 X 3 3 3 3 gt gt gt df ap1 X as1 X ap2 X a
  • 字典的嵌套列表

    我正在尝试创建dict通过嵌套list groups Group1 A B Group2 C D L y x 0 for y in x if y x 0 for x in groups d k v for d in L for k v in
  • 我可以使用 dask 创建 multivariate_normal 矩阵吗?

    有点相关这个帖子 https stackoverflow com questions 52337612 random multivariate normal on a dask array 我正在尝试复制multivariate norma
  • Python int 太大,无法放入 SQLite

    我收到错误 OverflowError Python int 太大 无法转换为 SQLite INTEGER 来自以下代码块 该文件约25GB 因此必须分部分读取 length 6128765 Works on partitions of
  • 在 pip.conf 中指定多个可信主机

    这是我尝试在我的中设置的 etc pip conf global trusted host pypi org files pythonhosted org 但是 它无法正常工作 参考 https pip pypa io en stable
  • 是否可以将 cython 函数作为参数传递给 scipy 函数?

    Scipy 有许多函数接受 python 可调用来执行某些操作 特别是 我正在使用数学优化函数scipy optimize leastsq接受 Python 可调用作为目标函数参数 该目标函数可以通过以下方式调用leastsq在最小化过程中
  • 是否可以强制浮点数的指数或有效数匹配另一个浮点数(Python)?

    这是我前几天试图解决的一个有趣的问题 是否可以强制一个的有效数或指数float与另一个人一样float在Python中 出现这个问题是因为我试图重新调整一些数据 以便最小值和最大值与另一个数据集匹配 然而 我重新调整后的数据略有偏差 大约小
  • 具有指定置信区间的 Seaborn 条形图

    我想在 Seaborn 条形图上绘制置信区间 但我已经计算出置信区间 如何让 Seaborn 绘制我的置信区间而不是尝试自行计算它们 例如 假设我有以下 pandas DataFrame x pd DataFrame Group 1 0 5
  • 将此 MATLAB 代码转换为 Python 时我做错了什么?

    我正在努力将生成波形的 MATLAB 代码转换为 Python 就上下文而言 这是原子力显微镜带激发响应的模拟 与代码错误无关 在 MATLAB 中从 r vec 生成的图形与我在 Python 中生成的图形不同 我是否正确地将 MATLA
  • 如何识别图形线条

    我有以下格式的路径的 x y 数据 示例仅用于说明 seq p1 p2 0 20 2 3 1 20 2 4 2 20 4 4 3 22 5 5 4 22 5 6 5 23 6 2 6 23 6 3 7 23 6 4 每条路径都有多个点 它们

随机推荐

  • 代码仅适用于 jsfiddle

    In this question I asked how I can generate shades of one color responsive to the number of div s DonJuwe came up with a
  • NonExistentClass 无法转换为 Annotation - app:kaptDebugAndroidTestKotlin

    我想使用 JUnit 5 测试一个类 但在 gradle 运行 app compileDebugAndroidTestKotlin 任务时我遇到了问题 我已经尝试过以下链接中的解决方案 但到目前为止没有任何帮助 NonExistentCla
  • cpp 文件中命名空间内常量的定义

    我在 VS 2010 中接近了这种奇怪的 对我来说 效果 任何聪明的人都可以解释一下吗 Header h include
  • 在 xamarin.forms 中使用 fontawesome(仅限 iOS 和 Android)

    在 xamarin 表单中 使用图标作为 png 文件对于您需要执行和验证的所有大小和本机内容非常痛苦 我决定使用很棒的字体 但这样我就无法放入工具栏项目 也无法放入某些也需要文本的按钮 有人有用作文件图像源的指南吗因为 fontimage
  • 如何解释统计数据 Z3

    我在 Z3 中得到以下统计数据 added eqs 24529 binary propagations 43837 bv bit2core 7115 bv conflicts 156 bv diseqs 10395 bv dynamic d
  • C# 等价于 C++ std::variant(求和类型/可区分联合)

    在 C 中我们有std variant用于创建一个总和类型 又名受歧视联盟 例如 以下内容将允许v持有一个std string or an int include
  • c++/boost program_options 一个选项禁用其他选项

    我有这样的代码 namespace po boost program options po options description desc Allowed options desc add options help produce hel
  • git mv 记录移动?

    调用时git mv file1 file2它是否在内部记录移动 用于日志中的历史跟踪 或者与调用完全相同mv file1 file2 git rm file1 and git add file2 git mv与您列出的三个操作完全相同 尽管
  • 用于绕过访问嵌套 iframe 的同源策略的用户脚本

    在以下 HTML 模型中 嵌套的 iframe 源自不同的子域 这会导致诸如以下的消息错误 访问属性 文档 的权限被拒绝 div div div div div div
  • 如何使用 Dart 的 JS 互操作创建匿名 JavaScript 函数/回调?

    我正在使用 Dart 及其JS 互操作 我需要将以下 JavaScript 代码转换为 Dart ID3 loadTags filename mp3 function var tags ID3 getAllTags filename mp3
  • Silverlight 用户控件句柄

    我有一个用 C 编写的 DLL Player dll 内部使用视窗GDI 我有一个用 Windows 窗体编写的应用程序 基本上是视频播放器 它在内部调用 APIPlayer dll渲染actual使用 p invoke 技术在屏幕上显示图
  • 在 Visual Studio 2015 中设置 OpenCV 3.1

    我已经下载了 opencv 3 1 我想在 Visual Studio 2015 中启动一个项目 我不知道如何将此库链接到我的项目 另外我想知道我是否可以继续使用这个 opencv 因为它只有 x64 并且我的项目不针对 64 位系统 下载
  • Access-Control-Allow-Methods 错误不允许方法 DELETE

    我已经使用 angularjs 开发了 RESTAPI 的前端 当我尝试使用 resource 编写 DELETE 时 它会给我以下错误 Access Control Allow Methods 不允许方法 DELETE 我也在用角度做一些
  • Rpy2 在安装时找不到我的 R 库

    R 从源代码构建 本地安装 R 位于 bin R 在我的路径中 及其库位于 lib64 R 安装 rpy2 应该很简单 它找到正确的 R 就好了 因为它在路径中 然后它找不到库 python setup py build install R
  • Java 从 Appengine 托管虚拟机连接到 Cloud SQL 第二代

    尝试为具有托管虚拟机的 Java Appengine 设置与 Clond SQL 第二代的连接 我得到了什么 VM 正在使用 Appengine Compat 模式 FROM gcr io google appengine java com
  • 面板中从右到左布局

    我有一个 Windows 项目 C 我们将用于阿拉伯 众所周知 国家遵循从右到左的机制 如何以 RTL 从右到左 格式移动面板中的所有控件位置 我已将属性 RightToLeft 和 RightToLeftLayout 设置为 true 但
  • 如何使用 css 在图像周围使用点 3 次 如何在移动设备上进行管理

    我正在使用 VueJS add vutify 进行项目 我创建了一个带有卡片的组件 其中包含两张卡片 我应该在两个不同版本的卡片周围显示点 一种用于桌面 一种用于移动 到目前为止 我已经实现了在桌面上显示点 我在底部创建了点 并通过 UX
  • Krajee 文件输入在表单提交上提交文件

    我正在使用这个插件来引导上传存储在带有提交按钮的表单中的文件 http plugins krajee com file input 我的问题是 a 是否有一种方法或方法可以检查 dropZone 中是否有尚未上传的文件 并在用户提交表单后通
  • 管理/员工面板的简单实现?

    新项目需要一个供管理员和工作人员使用的简单面板 页面 最好不要使用 SSL 或任何数字认证的东西 通过 http 简单登录就可以了 具有基本身份验证 仅允许管理员以管理员身份登录 以及 员工 组中的任何工作人员 理想情况下 凭据 用户名 哈
  • 为什么 scipy csr 矩阵的行索引比 numpy 数组慢

    我不确定我做错了什么 但似乎行索引 scipycsr matrix与 numpy 数组相比 速度大约慢 2 倍 参见下面的代码 csr 矩阵的行索引不应该比密集矩阵更快吗 因为只提取很少的非零元素 如下例所示 是否有技巧可以使 scipy