scipy稀疏矩阵和cython

时间:2014-08-21 16:00:55

标签: python numpy scipy cython sparse-matrix

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

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

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

1 个答案:

答案 0 :(得分:5)

以下示例迭代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:D慢约2倍,比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]
  • 使用np.ndarray[object, ndim=1] data
  • 声明data=m.data之类的缓冲区

不影响的事情:

  • boundscheckwraparound