【问题标题】:scipy sparse matrices and cythonscipy 稀疏矩阵和 cython
【发布时间】:2014-10-15 08:30:24
【问题描述】:

我需要在 Cython 方法中对 scipy 稀疏矩阵执行一组操作。

为了有效地应用这些,我需要访问lil_matrix 表示。 python中的lil(链表稀疏矩阵)数据表示使用不同长度的list of lists

如何有效地将不同长度的列表传递给 cython(不复制)? 有没有其他方法可以访问 cython 中的 lil 矩阵?

【问题讨论】:

标签: python numpy scipy cython sparse-matrix


【解决方案1】:

下面的示例遍历 lil_matrix 并计算每一行的总和。

注意我没有做任何声明,即使它非常快because Cython is already optimized for built-in types such as lists。时间也显示在下面...

import time

import numpy as np
cimport numpy as np

from scipy.sparse import lil_matrix

cdef iter_over_lil_matrix(m):
    cdef list sums, data_row
    sums = []
    for data_row in m.data:
        s = 0
        for value in data_row:
            s += value
        sums.append(s)
    return sums

def main():
    a = np.random.random((1e4*1e4))
    a[a>0.1] = 0
    a = a.reshape(1e4,1e4)
    m = lil_matrix(a)

    t0 = time.clock()
    sums = iter_over_lil_matrix(m)
    t1 = time.clock()
    print 'Cython lil_matrix Time', t1-t0

    t0 = time.clock()
    array_sums = a.sum(axis=1)
    t1 = time.clock()
    print 'Numpy ndarray Time', t1-t0

    t0 = time.clock()
    lil_sums = m.sum(axis=1)
    t1 = time.clock()
    print 'lil_matrix Time', t1-t0

    mcsr = m.tocsr()
    t0 = time.clock()
    csr_sums = mcsr.sum(axis=1)
    t1 = time.clock()
    print 'csr_matrix Time', t1-t0

    assert np.allclose(array_sums, sums)
    assert np.allclose(array_sums, np.asarray(lil_sums).flatten())
    assert np.allclose(array_sums, np.asarray(csr_sums).flatten())

时间以秒为单位 - 仅比超级优化的 NumPy 慢 2 倍:D,比 lil_matrix.sum() 方法快得多,因为它之前转换为 csr_matrix(),@hpaulj 澄清并由以下结果证实。请注意,列上的csr_matrix.sum() 几乎比密集和快一个数量级。

Cython lil_matrix Time 0.183935034665
Numpy ndarray Time 0.106583238273
lil_matrix Time 2.47158218631
csr_matrix Time 0.0140050888745

会使代码变慢的事情:

  • 使用for i in range(len(m.data)):data_row = m.data[i]
  • data=m.data 声明像np.ndarray[object, ndim=1] data 这样的缓冲区

没有影响的事情:

  • boundscheckwraparound

【讨论】:

  • 非常感谢,但这里的比较不公平。您应该将 lil-matrix summation 与此 cython 函数进行比较:即 m.sum(axis = 1) 而不是 a.sum(axis=1)。您能否也发布结果(比方阵更可取?)这里的矩阵a 也不是很稀疏。
  • @Siamak 我已经使用稀疏矩阵更新了答案,并与m.sum(axis=1) 进行了比较...请注意,所提出的方法更接近并最终将比 NumPy 对稀疏矩阵的性能更快。 ..
  • 感谢 Saullo,这些数字令人惊讶!我猜scipy 表现不佳的一个原因是矩阵不是很稀疏。
  • sparse sum 是具有适当向量的点积。要进行该数学运算,lil 将转换为 csr。使用您的样本矩阵,csr 总和比密集总和快 5 倍。 lil 总和很慢,因为将其转换为 csr 需要时间。
  • @hpaulj 感谢您提供宝贵的 cmets。我没有意识到这一点。我已经更新了答案,添加了csr_matrix 的时间以确认您的评论
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 2017-03-31
  • 2023-04-10
  • 2017-07-21
  • 2011-11-28
  • 2017-07-02
  • 2011-03-07
相关资源
最近更新 更多