私は繰り返しスパース行列を構築したい、とscipyのダウンロードのドキュメントによると、このために2つの適切なオプションがあることに気づい:なぜlil_matrixとdok_matrixはdictsの一般的なdictに比べて遅いのですか?
:クラスscipy.sparse.lil_matrix(引数1、形状=なし、dtype = None、 copy = False)[ソース]行ベースのリンクリストの疎行列
これは、疎行列 を段階的に構築するための効率的な構造です。
クラスscipy.sparse.dok_matrix(ARG1、形状=なし、DTYPE =なし、 コピー=偽)[ソース]キーの辞書ベースの疎行列。
これは、疎行列 を段階的に構築するための効率的な構造です。
しかし、私は(後で簡単に疎行列に変換することができます)値の辞書の辞書を構築することに比較するベンチマークを実行しているとき、後者は約10〜20倍の速さのいずれかを使用してよりであることが判明疎行列モデル:
from scipy.sparse import dok_matrix, lil_matrix
from timeit import timeit
from collections import defaultdict
def common_dict(rows, cols):
freqs = defaultdict(lambda: defaultdict(int))
for row, col in zip(rows, cols):
freqs[row][col] += 1
return freqs
def dok(rows, cols):
freqs = dok_matrix((1000,1000))
for row, col in zip(rows, cols):
freqs[row,col] += 1
return freqs
def lil(rows, cols):
freqs = lil_matrix((1000,1000))
for row, col in zip(rows, cols):
freqs[row,col] += 1
return freqs
def benchmark():
cols = range(1000)
rows = range(1000)
res = timeit("common_dict({},{})".format(rows, cols),
"from __main__ import common_dict",
number=100)
print("common_dict: {}".format(res))
res = timeit("dok({},{})".format(rows, cols),
"from __main__ import dok",
number=100)
print("dok: {}".format(res))
res = timeit("lil({},{})".format(rows, cols),
"from __main__ import lil",
number=100)
print("lil: {}".format(res))
結果:
benchmark()
common_dict: 0.11778324202168733
dok: 2.2927695910912007
lil: 1.3541790939634666
それは行列モデルのためのそのようなオーバーヘッドが発生し、それをスピードアップするためにいくつかの方法があることは何ですか? dokまたはlilのいずれかがdictsの一般的なdictよりも好む場合があります。それぞれの時間が半分にカットされている
for row, col in zip(rows, cols):
#freqs[row,col] += 1
freqs[row,col] = 1
:私はあなたの2つのスパース配列のためのあなたの+=
にちょうど=
を変更
私のシステムでは、 'fast_dok'は' common_dict'より約4倍遅く、 'tuple_dict'よりも8倍遅いです。これは私があなたの最初の例を呼んだものです。 –
Cont:私は確信していません。なぜなら、すべてのペアに対して 'dict'を作成しているか、あるいは' dok_matrix'が 'get()'をオーバーライドしていなかったかもしれないからです。幸運なことに、 'update()'はまだオーバーライドされていないので、最初の解決策が動作し、非常に高速です。 1つの注意点: 'defaultdict'中の' 0'も 'dok_matrix'によって格納されます。幸いにも、データを例えば'csr_matrix'を呼び出し、' eliminate_zeros() 'を呼び出します。 –
Py3.6には新しい 'dict'コード(デフォルトの命令など)があり、速度の変更がある可能性があります。 – hpaulj