具有重复索引的最快添加:np.add.at/sparse.csr_matrix?

2023-12-14

说我有一个num_indices * n指数矩阵(在range(m)) and a num_indices * n值矩阵,即

m, n = 100, 50
num_indices = 100000
indices = np.random.randint(0, m, (num_indices, n))
values = np.random.uniform(0, 1, (num_indices, n))

我想得到一个形状的结果矩阵m * n,这样每一列都会被索引并在索引和值矩阵中的相应列上求和。以下是一些实现:

  • 基本的for循环
tic = time.time()
res1 = np.zeros((m, n))
for i in range(num_indices):
    for j in range(n):
        res1[indices[i, j], j] += values[i, j]
print(f'element-wise for loop used {time.time() - tic:.5f}s')
  • np.add.at,多维
tic = time.time()
res2 = np.zeros((m, n))
np.add.at(res2, (indices, np.arange(n)[None, :]), values)
print(f'np.add.at used {time.time() - tic:.5f}s')
  • np.add.at,带有 for 循环
tic = time.time()
reslst = []
for colid in range(n):
    rescol = np.zeros((m, 1))
    np.add.at(rescol, (indices[:, colid], np.zeros(num_indices, dtype=int)), values[:, colid])
    reslst.append(rescol)
res3 = np.hstack(reslst)
print(f'np.add.at with loop used {time.time() - tic:.5f}s')
  • scipy.sparse,多维
from scipy import sparse
tic = time.time()
res4 = sparse.csr_matrix((values.ravel(), (indices.ravel(), np.tile(np.arange(n), num_indices))), shape=(m, n)).toarray()
print(f'sparse.csr used {time.time() - tic:.5f}s')
  • scipy.sparse,带有 for 循环
tic = time.time()
reslst = []
for colid in range(n):
    rescol = sparse.csr_matrix((values[:, colid], (indices[:, colid], np.zeros(num_indices, dtype=int))), shape=(m, 1)).toarray()
    reslst.append(rescol)
res5 = np.hstack(reslst)
print(f'sparse.csr with loop used {time.time() - tic:.5f}s')

结果都是一样的:

assert np.isclose(res2, res1).all()
assert np.isclose(res3, res1).all()
assert np.isclose(res4, res1).all()
assert np.isclose(res5, res1).all()

然而,速度很奇怪,而且不令人满意:

for loop used 1.69889s
np.add.at used 0.17287s
np.add.at with loop used 0.47767s
sparse.csr used 0.16847s
sparse.csr with loop used 0.09845s

我的基本问题是:

  • Why is np.add.at这么慢 - 甚至比scipy.sparse?我认为 numpy 会受益匪浅,尤其是在多维情况下。
  • For scipy.sparse,为什么多维比for循环还慢?没有使用并发吗? (为什么对于 numpy 来说,多维更快?)
  • 总的来说,有没有更快的方法来实现我想要的?

令人惊讶的是,事实证明np.add.at在 Numpy 中实现效率非常低.

关于scipy.sparse,我无法在我的机器上使用 Scipy 1.7.1 重现相同的性能改进:它只是快一点。就像 Numpy 的np.add.at,还远远谈不上快。

您可以使用以下命令有效地实现此操作Numba:

import numba as nb

@nb.njit('(int_[:,::1], float64[:,::1], int_, int_)')
def compute(indices, values, n, m):
    res = np.zeros((m, n), dtype=np.float64)
    for i in range(num_indices):
        for j in range(n):
            #assert 0 <= indices[i, j] < m
            res[indices[i, j], j] += values[i, j]
    return res

tic = time.time()
result = compute(indices, values, n, m)
print(f'Numba used {time.time() - tic:.5f}s')

请注意,该函数假设indices包含有效值(即没有越界)。否则,该函数可能会崩溃或默默地损坏程序。如果您不确定,您可以启用断言,但代价是计算速度较慢(在我的机器上慢两倍)。

请注意,只要满足以下条件,此实现就会很快8 * n * m足够小,所以输出数组适合L1缓存(一般为 16 KB 到 64 KB)。否则,由于随机访问模式效率低下,它可能会慢一些。如果输出数组不适合 L2 缓存(通常为几百 KB),那么速度会明显变慢。

Results

element-wise for loop used 2.45158s
np.add.at used 0.28600s
sparse.csr used 0.19600s
sparse.csr with loop used 0.18900s
Numba used 0.00500s

Thus, Numba 大约快 40 倍比最快的实现快,比最慢的实现快约 500 倍。 numba 代码速度要快得多,因为与 Numpy 和 Scipy 相比,代码被编译为优化的本机二进制文件,没有额外的开销(即边界检查、临时数组、函数调用)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有重复索引的最快添加:np.add.at/sparse.csr_matrix? 的相关文章

  • Python 中的 Lanczos 插值与 2D 图像

    我尝试重新缩放 2D 图像 灰度 图像大小为 256x256 所需输出为 224x224 像素值范围从 0 到 1300 我尝试了两种使用 Lanczos 插值来重新调整它们的方法 首先使用PIL图像 import numpy as np
  • Django 管理员在模型编辑时间歇性返回 404

    我们使用 Django Admin 来维护导出到我们的一些站点的一些数据 有时 当单击标准更改列表视图来获取模型编辑表单而不是路由到正确的页面时 我们会得到 Django 404 页面 模板 它是偶尔发生的 我们可以通过重新加载三次来重现它
  • 将数据从 python pandas 数据框导出或写入 MS Access 表

    我正在尝试将数据从 python pandas 数据框导出到现有的 MS Access 表 我想用已更新的数据替换 MS Access 表 在 python 中 我尝试使用 pandas to sql 但收到错误消息 我觉得很奇怪 使用 p
  • OpenCV Python cv2.mixChannels()

    我试图将其从 C 转换为 Python 但它给出了不同的色调结果 In C Transform it to HSV cvtColor src hsv CV BGR2HSV Use only the Hue value hue create
  • 使用 matplotlib 绘制时间序列数据并仅在年初显示年份

    rcParams date autoformatter month b n Y 我正在使用 matpltolib 来绘制时间序列 如果我按上述方式设置 rcParams 则生成的图会在每个刻度处标记月份名称和年份 我怎样才能将其设置为仅在每
  • Python - StatsModels、OLS 置信区间

    在 Statsmodels 中 我可以使用以下方法拟合我的模型 import statsmodels api as sm X np array 22000 13400 47600 7400 12000 32000 28000 31000 6
  • Flask 会话变量

    我正在用 Flask 编写一个小型网络应用程序 当两个用户 在同一网络下 尝试使用应用程序时 我遇到会话变量问题 这是代码 import os from flask import Flask request render template
  • SQLALchemy .query:类“Car”的未解析属性引用“query”

    我有一个这里已经提到的问题https youtrack jetbrains com issue PY 44557 https youtrack jetbrains com issue PY 44557 但我还没有找到解决方案 我使用 Pyt
  • 测试 python Counter 是否包含在另一个 Counter 中

    如何测试是否是pythonCounter https docs python org 2 library collections html collections Counter is 包含在另一个中使用以下定义 柜台a包含在计数器中b当且
  • 以编程方式停止Python脚本的执行? [复制]

    这个问题在这里已经有答案了 是否可以使用命令在任意行停止执行 python 脚本 Like some code quit quit at this point some more code that s not executed sys e
  • 如何在Python中获取葡萄牙语字符?

    我正在研究葡萄牙语 角色看起来很奇怪 我怎样才能解决这个问题 代码 import feedparser import random Vou definir os feeds feeds conf feedurl http pplware s
  • 添加不同形状的 numpy 数组

    我想添加两个不同形状的 numpy 数组 但不进行广播 而是将 缺失 值视为零 可能最简单的例子是 1 2 3 2 gt 3 2 3 or 1 2 3 2 1 gt 3 2 3 1 0 0 我事先不知道形状 我正在弄乱每个 np shape
  • 在f字符串中转义字符[重复]

    这个问题在这里已经有答案了 我遇到了以下问题f string gt gt gt a hello how to print hello gt gt gt f a a gt gt gt f a File
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 无法在 Python 3 中导入 cProfile

    我试图将 cProfile 模块导入 Python 3 3 0 但出现以下错误 Traceback most recent call last File
  • 如何在seaborn displot中使用hist_kws

    我想在同一图中用不同的颜色绘制直方图和 kde 线 我想为直方图设置绿色 为 kde 线设置蓝色 我设法弄清楚使用 line kws 来更改 kde 线条颜色 但 hist kws 不适用于显示 我尝试过使用 histplot 但我无法为
  • Conda SafetyError:文件大小不正确

    使用创建 Conda 环境时conda create n env name python 3 6 我收到以下警告 Preparing transaction done Verifying transaction SafetyError Th
  • 使用 Python 绘制 2D 核密度估计

    I would like to plot a 2D kernel density estimation I find the seaborn package very useful here However after searching
  • 使用其构造函数初始化 OrderedDict 以便保留初始数据的顺序的正确方法?

    初始化有序字典 OD 以使其保留初始数据的顺序的正确方法是什么 from collections import OrderedDict Obviously wrong because regular dict loses order d O
  • Python 类继承 - 诡异的动作

    我观察到类继承有一个奇怪的效果 对于我正在处理的项目 我正在创建一个类来充当另一个模块的类的包装器 我正在使用第 3 方 aeidon 模块 用于操作字幕文件 但问题可能不太具体 以下是您通常如何使用该模块 project aeidon P

随机推荐

  • 为什么当 'let' 表达式计算结果为 0 时,带有 -e 选项的 Bash 会退出? [复制]

    这个问题在这里已经有答案了 我很难理解为什么会这样 e选项退出此脚本 仅当计算的表达式给出时才会发生0 bin bash set ex table year 1979 1982 1980 1993 1995 year 1 let indic
  • C++20 中的 `constinit` 是什么?

    constinit是一个新的keyword and 说明符在 C 20 中提出P1143 标准中提供了以下示例 const char g return dynamic initialization constexpr const char
  • 分布式锁服务[关闭]

    Closed 这个问题是基于意见的 目前不接受答案 您会使用哪种分布式锁服务 要求是 不同进程 机器可以看到的互斥 锁 锁定 释放语义 一定超时后自动释放锁 如果锁持有者死亡 它将在 X 秒后自动释放 Java实现 很高兴拥有 Net 实现
  • 自定义轮播间隔?

    在 Bootstrap 3 中 使用 jQuery 有没有一种方法可以按轮播的索引进行排序并添加每张幻灯片的自定义间隔 以便我可以让一张幻灯片 10000 毫秒 另一张幻灯片 500 毫秒等 我知道您可以设置数据间隔属性 但这会设置所有幻灯
  • 如何使用asp.net core从appsettings.json获取配置数据并做出反应

    我正在使用带有react redux的asp net core 并且我正在尝试将react redux中的配置数据移动到appsettings json文件中 但是一旦配置数据被移动 ClientApp 如何访问配置数据 我正在将 Reac
  • Google 地图:相对于固定定位

    我正在寻找的效果是 我有一个浮动的 div 里面有 Google 地图 当用户向下滚动时 我希望它固定在 top 0px 这基本上就是 Yelp 搜索页面上的地图 有几个类似的问题询问如何使用 JQuery 将 div 的类更改为固定 一旦
  • 在带有参数的函数上使用 Invoke-Command -ScriptBlock

    我正在编写一个 PowerShell 脚本 它将使用以下命令在远程主机上执行命令调用命令和它的 ScriptBlock范围 例如 function Foo return foo rv Invoke Command Credential c
  • 强制使用 buildout 和 zc.recipe.egg:scripts 制作的脚本进行无缓冲输出

    我需要在使用构建构建的脚本中使用无缓冲的输出 我的方法是指定 u生成的脚本中的 Python 标志 这是我的 buildout cfg buildout parts python develop python recipe zc recip
  • 如何提供中国计算机软件著作权证书

    我最近将该应用程序发布到了华为应用市场 中国境外已获批准 但在中国大陆却遭到拒绝 他们要求我提供计算机软件著作权证书 如何拥有计算机软件著作权证书来提供华为应用市场 华为应用市场发送的所有邮件信息如下 亲爱的开发者 感谢您与我们联系 您的应
  • 在 R 中安装 RSelenium 时出错

    当我尝试安装时出现以下错误RSelenium包裹 install packages RSelenium Installing package into C Users nshukla Documents R win library 3 2
  • 使用 Anorm 批量插入具有多列的表

    我正在尝试使用 Anorm 在 play 框架 2 3 1 中 批量插入 MySQL 数据库表 我正在构建的应用程序除了需要批量数据插入之外还有一个标准的 Web 前端 我想尝试将逻辑保留在同一软件堆栈上 插入仅进入相同的几个表 一次插入的
  • 在 MKPolyLineView 中绘制 CAGradient

    我的 MKPolyLineView 有问题 我只是尝试对折线进行颜色渐变 但使用 CAGradient 它确实有效 我对 MKPolylineView 进行子类化并在中重绘 void drawMapRect MKMapRect mapRec
  • VS Installer Solution 警告错误:编译期间“DLL 文件受 Windows 系统文件保护”

    I m building an 安装人员解决方案对于 C 中的 VS 项目 在编译过程中我得到以下信息warnings WARNING System Linq dll should be excluded because its sourc
  • 快速 Pythonic 方法将许多字符串列表转换为浮点数列表,同时捕获 ValueErrors

    我有大约 5000 万个 Python 字符串列表 如下所示 1 1 0 foobar 3 0 我需要将它们转换为浮点数和 None 的列表 如下所示 1 0 1 0 None None 3 0 目前我使用一些代码 例如 def to fl
  • 迭代对象中的项目,查找匹配项并替换

    我有一个以以下格式返回的对象 category Coach phrase original Training the team to develop their match skills by ensuring they are comfo
  • 如何识别网站是否源自移动浏览器?

    为手机开发网站是一个完全不同的世界吗 如何检测页面是从电脑访问还是从手机访问 我问这个是因为我看到如下代码 if isset SERVER HTTP ACCEPT strpos SERVER HTTP ACCEPT vnd wap wml
  • 无法重新绘制我的 JFrame/JPanel

    我创建了一个程序 可以在屏幕上移动一个球 我曾经把所有的东西都放在一个类中 但觉得它看起来太乱了 所以我把它分成了三个不同的类 Main 初始化所有东西 Game 它绘制所有东西并且是一个 JPanel 而 AL 是KeyListener
  • es6 import 的副作用含义

    我正在阅读 es6 import 声明MDN 上的参考 语法 import my module 将导入整个模块仅用于副作用 而不导入任何绑定 我不知道什么副作用意思是 我一直在使用angular通过说import angular Angul
  • JScrollPane 中组件的面向列的布局

    我正在开发我的第一个 Swing 应用程序 并且在为用户创建用于在某些字段中输入值的对话框窗口时遇到布局问题 由于显示的字段数量根据用户选择而变化 因此我在对话框中使用 JScrollPane 将其视口设置为向其中添加字段组件的面板 对于要
  • 具有重复索引的最快添加:np.add.at/sparse.csr_matrix?

    说我有一个num indices n指数矩阵 在range m and a num indices n值矩阵 即 m n 100 50 num indices 100000 indices np random randint 0 m num