我需要在一个Cython
方法中对scipy稀疏矩阵执行一组操作。
为了高效地应用这些操作,我需要访问lil_matrix
表示。
Python中的lil(链接列表稀疏矩阵)数据表示使用不同长度的列表的列表
。
如何有效地将不同长度的列表传递给cython(而不进行复制)? 是否有其他方法可以在cython中访问lil矩阵?
我需要在一个Cython
方法中对scipy稀疏矩阵执行一组操作。
为了高效地应用这些操作,我需要访问lil_matrix
表示。
Python中的lil(链接列表稀疏矩阵)数据表示使用不同长度的列表的列表
。
如何有效地将不同长度的列表传递给cython(而不进行复制)? 是否有其他方法可以在cython中访问lil矩阵?
lil_matrix
并计算每行的总和。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]
np.ndarray[object, ndim=1] data
,并使用data=m.data
不会影响的东西:
boundscheck
或wraparound
m.sum(axis = 1)
而不是a.sum(axis=1)
。您能否也发布一下那个结果(最好是在一个方阵上)?此外,这里的矩阵a
并不是非常稀疏。 - SKVm.sum(axis=1)
进行比较...请注意,所提出的方法越来越接近于 NumPy 在稀疏矩阵上的性能,最终会比 NumPy 更快... - Saullo G. P. Castroscipy
性能不佳的一个原因是矩阵不是非常稀疏。 - SKVcsr_matrix
的时间来确认您的评论。 - Saullo G. P. Castro
lil_matrix
...然后你可以使用那个答案中提出的解决方案,其中数据类型是已知的... - Saullo G. P. Castro