2017-06-11 5 views
0

ランダムなハッシュマップh:[n] - > [t]の疎行列表現を作成しようとしています。これは各iをを利用可能なd個の位置それらの場所の値は、いくつかの離散分布から引き出されます。ここでscipyの置換えなしでゆっくりランダムなサンプル生成

:param d: number of bins 
:param n: number of items hashed 
:param s: sparsity of each column 
:param distribution: distribution object. 

は私の試みです:

start_time=time.time() 
distribution = scipy.stats.rv_discrete(values=([-1.0, +1.0 ], [0.5, 0.5]),name = 'dist') 

data = (1.0/sqrt(self._s))*distribution.rvs(size=self._n*self._s) 
col = numpy.empty(self._s*self._n) 
for i in range(self._n): 
    col[i*self._s:(i+1)*self._s]=i 

row = numpy.empty(self._s*self._n) 

print time.time()-start_time 

for i in range(self._n): 
    row[i*self._s:(i+1)*self._s]=numpy.random.choice(self._d, self._s, replace=False) 

S = scipy.sparse.csr_matrix((data, (row, col)), shape = (self._d,self._n)) 

print time.time()-start_time 

return S 

今すぐnの= 500000このマップを作成するために、S = 10、D = 1000、それはここで、私のまともなワークステーション上で20代を中心に私を取っています行インデックスの生成には90%の時間がかかります。これをスピードアップするためにできることはありますか?他の選択肢はありますか?ありがとう。

答えて

1
col = numpy.empty(self._s*self._n) 
for i in range(self._n): 
    col[i*self._s:(i+1)*self._s]=i 

は、1つの非ループ式として記述できるようなものです。それはおそらく大きな時間の消費者ではありません。

私の最初の推測は - ですが、私はこれを確実にする必要があります。私はすべての行に列のインデックス番号を割り当てていると思います。以下のための同様の

col = np.empty(self._s, self._n) 
col[:,:] = np.arange(self._n) 
col = col.ravel() 

何か:

for i in range(self._n): 
    row[i*self._s:(i+1)*self._s]=numpy.random.choice(self._d, self._s, replace=False) 

_d_n回から_s値を選んで、私が思うに、です。 _sに沿ってno-replaceを実行しますが、_nのreplaceを許可するのは難しいことがあります。

コードを自分で実行しないでください(小さいn)私はちょっとうんざりしています。遅い部分はどれですか、col,row、または最終的にcsrを生成していますか? n=500000の反復は遅くなるでしょう。

行列は(1000、500000)ですが、(10 * 500000)の非ゼロ項目です。だから.01のまばゆい。ただ、比較のために、同様のサイズとスパース

In [5]: %timeit sparse.random(1000, 500000, .01) 
1 loop, best of 3: 24.6 s per loop 

と密なランダムな選択のスパースランダム行列を生成するために興味深いものになるだろう:

In [8]: timeit np.random.choice(1000,(10,500000)).shape 
10 loops, best of 3: 53 ms per loop 
In [9]: np.array([np.random.choice(1000,(10,)) for i in range(500000)]).shape 
Out[9]: (500000, 10) 
In [10]: timeit np.array([np.random.choice(1000,(10,)) for i in range(500000)]). 
    ...: shape 
1 loop, best of 3: 12.7 s per loop 

だから、はい、大きな反復ループは高価です。しかし、その取り替え方針を考えれば、それを回避する方法はないかもしれない。それとも?

最初の推測として、rowを作成すると半分の時間がかかり、残りの半分は疎の行列になります。私は驚いていない。 cooの入力形式を使用していますが、に変換する場合は、lexsortingと重複の合計が必要です。 indptrタイプの入力を使用するとスピードを上げることができます。合計に重複はありません。また、行当たり10の非ゼロ項が常に存在するため、indptrの値を生成することは難しくありません。しかし、私は頭の上からそれを行うことはできません。 (oops、それは転置です)。

In [11]: %timeit sparse.random(1000, 500000, .01, 'csr') 
1 loop, best of 3: 28.3 s per loop 
+0

ありがとう:csrにスパース

randomは少しだけ遅くなります。はい、行インデックスを生成する時間は90%です。あなたはこれを助けることができるいくつかの他の選択肢について考えますか?これは私の目的にとっては遅すぎるということです。 – user1131274

関連する問題