【问题标题】:Optimizing iteration using itertools.izip使用 itertools.izip 优化迭代
【发布时间】:2014-10-02 09:25:30
【问题描述】:

我有一个算法可以遍历矩阵的所有非零值,如下所示:

for row, col, val in itertools.izip(matrix.row, matrix.col, matrix.data):
    dostuff(row, col, val)

我意识到这是在numpy 中迭代稀疏矩阵的最快方法,正如在Iterating through a scipy.sparse vector (or matrix) 中讨论的那样。

我的问题是我在每次求值时执行的函数需要另一个向量,我们称之为vec,如果vec[row] 等于0,则不执行任何操作,在某些情况下,大多数行都是如此.

因此,我不想遍历矩阵中的所有非零三元组(row, col, val) vec[row] != 0

我目前做的是简单而愚蠢的解决方案

import numpy as np
import scipy.sparse as sp
import itertools

N = 10000
matrix = sp.rand(N, N, density=0.0001, format='coo', dtype=None, random_state=None)
vec = np.zeroes(N)
s = 0
for row, col, val in itertools.izip(matrix.row, matrix.col, matrix.data):
    if vec[row] != 0:
        s += vec[row] * val # in reality, some other function is here

如果vec[row]!=0 的行数不多,它比原始代码运行得更快。但是,在vec 的所有值都非零的情况下,代码运行缓慢,这是我不允许忽略的情况(例如,如果vec=np.ones(len(matrix.data))

因此,我需要izip 的某种扩展,这将允许我“有条件地”迭代其输出,这样我就可以编写类似

for row, col, val in itertools.izip(matrix.row, matrix.col, matrix.data, lambda x: vec[x[0]] !> 0):
    dostuff(row, col, val)

你有什么建议?最快的方法是什么?

【问题讨论】:

  • 好吧,您仍然缺少导入。但足够接近;我能够测试我的想法并让它们发挥作用,这是重要的部分。

标签: python numpy sparse-matrix


【解决方案1】:

你可以只对行、列和数据使用 Numpy 的特殊索引:

which = vec[matrix.row] != 0

rows = matrix.row[which]
cols = matrix.col[which]
data = matrix.data[which]

for row, col, val in itertools.izip(rows, cols, data):
    s += vec[row] * val

【讨论】:

  • 看起来很棒,谢谢。我会尝试一下,看看我的算法会变得多快。如果您不介意,我将问题留待一段时间,看看是否有其他建议进来,否则我会接受这个问题。
  • 这是一个了不起的解决方案。如果vec 没有非零元素,则原始代码现在的运行速度仍比修改后的代码快约 20%,但如果vec 是稀疏的,则此代码的运行速度要快 2 到 3 个数量级。谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-07-14
  • 2021-07-25
  • 2013-05-29
  • 1970-01-01
  • 2020-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多