2016-04-11 19 views
3

csr疎行列といくつかの点リストに格納されているすべての点間のユークリッド距離を計算する必要があります。私がcsrを密なものに変換する方が簡単ですが、記憶がないためにできなかったので、それをcsrとして保管する必要があります。使用scipy csr行列のユークリッド距離を計算する

center 
array([[0, 1, 2, 2, 4, 1], 
     [3, 4, 1, 2, 4, 0]]) 

data_csr 
(0, 2) 4 
(1, 0) 1 
(1, 4) 2 
(2, 0) 2 
(2, 3) 1 
(3, 5) 1 
(4, 0) 4 
(4, 2) 3 
(4, 3) 2 

data_csr.todense() 
[[0, 0, 4, 0, 0, 0] 
[1, 0, 0, 0, 2, 0] 
[2, 0, 0, 1, 0, 0] 
[0, 0, 0, 0, 0, 1] 
[4, 0, 3, 2, 0, 0]] 

この中心点のリスト:

だから、例えば私はこのdata_csr疎行列(両方のビュー、CSRと密)を有しますscipy.spatialパッケージの場合、のデータ_csrの間のユークリッド距離の配列はのようになりますeを下にします。したがって、中心の各行の合計6点の各点は、data_csrのすべての行に対して計算されました。結果配列(2,5)の最初の行は、の中心の最初の行とすべての行data_csrの間のEDです。

data_csr.data 
array([4, 1, 2, 2, 1, 1, 4, 3, 2]) 

data_csr.indices 
array([2, 0, 4, 0, 3, 5, 0, 2, 3]) 

しかし、それでもまだ、私は間のEDを計算する方法を見つけ出すことはできません:私はこれまでのところ私はゼロ以外の値にもインデックスを得ることができることを学んだ

scipy.spatial.distance.cdist(center, data_csr, 'euclidean') 

array([[ 5.09901951, 3.87298335, 5.19615242, 5.  , 5.91607978], 
     [ 7.34846923, 5.38516481, 5.91607978, 6.8556546 , 6.08276253]]) 


これらの2つのオブジェクト。

+1

? – Alexander

+0

@Alexander私は編集しました。私は 'scipy.spatial.distance.cdist(center、data_csr、 'euclidean')'を使用します。 –

+0

上記の距離を計算するために結果を複製することはできません。マトリックスからデータを抽出する方法については、この記事を参照してください。これは私が持っている限りです。 http://stackoverflow.com/questions/36587702/convert-sparse-matrix-csc-matrix-to-pandas-dataframe/36587845#36587845 – Alexander

答えて

2

ので

In [114]: data=[4,1,2,2,1,1,4,3,2] 
In [115]: col=[0,1,1,2,2,3,4,4,4] 
In [116]: row=[2,0,4,0,3,5,0,2,3] 
In [117]: M=sparse.csr_matrix((data,(col,row))) 

In [118]: M 
Out[118]: 
<5x6 sparse matrix of type '<type 'numpy.int32'>' 
    with 9 stored elements in Compressed Sparse Row format> 

In [119]: M.A 
Out[119]: 
array([[0, 0, 4, 0, 0, 0], 
     [1, 0, 0, 0, 2, 0], 
     [2, 0, 0, 1, 0, 0], 
     [0, 0, 0, 0, 0, 1], 
     [4, 0, 3, 2, 0, 0]]) 

In [121]: center=np.array([[0,1,2,2,4,1],[3,4,1,2,4,0]]) 

それでは、どのように距離を計算した(あまりにも悪いあなたは、私がコピー-N-ペーストができ、入力を与えていない)のは、あなたの行列を作成してみましょうか? M.Aが(5,6)であり、centerが(2,6)である。これら2つの配列で何をしているのかは明らかではありません。

「生の」スパース値へのアクセスに関しては、coo形式が最もわかりやすいです。それは私がマトリックス

In [131]: M.tocoo().data 
Out[131]: array([4, 1, 2, 2, 1, 1, 4, 3, 2]) 

In [132]: M.tocoo().col 
Out[132]: array([2, 0, 4, 0, 3, 5, 0, 2, 3]) 

In [133]: M.tocoo().row 
Out[133]: array([0, 1, 1, 2, 2, 3, 4, 4, 4]) 

csr格納dataindicesindptrアレイで同じ情報を作成するために使用される同一の行、列、データのものです。しかし、最後の2からのi,jの値を引き出すために数学をする必要があります。csrこれらの配列をうまく利用する乗算ルーチンです。

一般に、加算/減算よりもcsr行列を乗算する方が良いです。

さらに詳しい説明が必要です。私たちが行う必要がある何


spatial.distance.cdist(center,M.A, 'euclidean') 
Out[156]: 
array([[ 5.09901951, 3.87298335, 5.19615242, 5.  , 5.91607978], 
     [ 7.34846923, 5.38516481, 5.91607978, 6.8556546 , 6.08276253]]) 

この機能を研究し、その入力を理解しています。私たちはドキュメントを超えてコードを見なければならないかもしれません。

このコードを見ると、xBが2dの配列であり、同じ数の列がxAであることを確認する手順があります。その後euclidianのためには、いくつかのCコードのラッパーのように見えます

_distance_wrap.cdist_euclidean_wrap(_convert_to_double(XA), 
            _convert_to_double(XB), dm) 

を呼び出します。私はそれを疎な行列にする方法を想像することはできません。

行を反復処理できます。 distM[[0],:].Aと呼ぶのは、速度を除いてM.A[[0],:]と同じです。スパース行列の行を反復することは、それぞれの反復で新しいスパース行列を構築する必要があるため、それほど遅くはありません。 csrおよびlilは、行の反復処理で2番目に高速です。私は時間のテストをスキップします今のところ

def foo(a,b,n): 
    # make a dense array from data,row 
    res = np.zeros((1,n)) 
    res[0,b]=a 
    return res 

In [190]: Ml=M.tolil() 

In [191]: Ml.data 
Out[191]: array([[4], [1, 2], [2, 1], [1], [4, 3, 2]], dtype=object) 

In [192]: Ml.rows 
Out[192]: array([[2], [0, 4], [0, 3], [5], [0, 2, 3]], dtype=object) 

In [193]: rowgen=(foo(a,b,6) for a,b in zip(Ml.data,Ml.rows)) 

In [194]: np.concatenate([spatial.distance.cdist(center,row, 'euclidean') for row in rowgen],axis=1) 
Out[194]: 
array([[ 5.09901951, 3.87298335, 5.19615242, 5.  , 5.91607978], 
     [ 7.34846923, 5.38516481, 5.91607978, 6.8556546 , 6.08276253]]) 

:直接lil形式の属性に反復 -

はここで速いかもしれない何か。

+0

私はケースを編集し、どのように計算したのか説明しました理解する。 'scipy.spatial.distance.cdist(center、data_csr、 'euclidean')を使って、 –

3

スパース行列の対になるユークリッド距離がsklearnで実装されています(hpauljによって指摘されているように、scipy実装はスパース行列では機能しません)。 hpaulj例に

例:

import scipy.sparse 
import sklearn.metrics.pairwise 
data = [4,1,2,2,1,1,4,3,2] 
col = [0,1,1,2,2,3,4,4,4] 
row = [2,0,4,0,3,5,0,2,3] 
M = scipy.sparse.csr_matrix((data,(col,row))) 
distances = sklearn.metrics.pairwise.pairwise_distances(M,M) 

ドキュメント:あなたはdata_csrとセンターED(密な仮定)を計算するにはどうすればよいhttp://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.pairwise_distances.html

関連する問題