scipy.sparse
行または列ベースのフォーマットを使用してください:csc_matrix
およびcsr_matrix
.
これらは内部で効率的な C 実装 (乗算を含む) を使用し、転置はtranspose(copy=False)
numpy 配列と同様にノーオペレーションです (特に を呼び出す場合)。
編集: ipythonによるいくつかのタイミング:
import numpy, scipy.sparse
n = 100000
x = (numpy.random.rand(n) * 2).astype(int).astype(float) # 50% sparse vector
x_csr = scipy.sparse.csr_matrix(x)
x_dok = scipy.sparse.dok_matrix(x.reshape(x_csr.shape))
現在x_csr
、 とx_dok
は 50% 疎です:
print repr(x_csr)
<1x100000 sparse matrix of type '<type 'numpy.float64'>'
with 49757 stored elements in Compressed Sparse Row format>
そしてタイミング:
timeit numpy.dot(x, x)
10000 loops, best of 3: 123 us per loop
timeit x_dok * x_dok.T
1 loops, best of 3: 1.73 s per loop
timeit x_csr.multiply(x_csr).sum()
1000 loops, best of 3: 1.64 ms per loop
timeit x_csr * x_csr.T
100 loops, best of 3: 3.62 ms per loop
だから私は嘘をついたようです。転置は非常に安価ですが、(最新の scipy 0.9.0 では) csr * csc の効率的な C 実装はありません。各呼び出しで新しい csr オブジェクトが構築されます :-(
ハックとして (最近の scipy は比較的安定していますが)、スパース データに対して直接ドット積を実行できます。
timeit numpy.dot(x_csr.data, x_csr.data)
10000 loops, best of 3: 62.9 us per loop
この最後のアプローチは、再びnumpy密な乗算を行うことに注意してください。スパース性は 50% であるため、実際にdot(x, x)
は 2 倍より高速です。