2015-12-14 15 views
5

私は疎行行列の各行の非ゼロ値の平均を計算しようとしています。マトリックスの平均メソッドを使用して、それをしない:スパース行列のゼロ以外の値の平均?

>>> from scipy.sparse import csr_matrix 
>>> a = csr_matrix([[0, 0, 2], [1, 3, 8]]) 
>>> a.mean(axis=1) 
matrix([[ 0.66666667], 
     [ 4.  ]]) 

を以下の作品が、大きな行列のために遅いです:速い方法があるかどう

>>> import numpy as np 
>>> b = np.zeros(a.shape[0]) 
>>> for i in range(a.shape[0]): 
... b[i] = a.getrow(i).data.mean() 
... 
>>> b 
array([ 2., 4.]) 

誰も私に教えていただけますか?

(x,y,z)=scipy.sparse.find(a) 

返す行(x)、スパース行列の列(y)と値(z):

答えて

4

これは、あなたが、私は三つの機能を利用したこのためnumpy.bincount.を使用することができ、一般的な問題と思われます。インスタンスの場合、xarray([0, 1, 1, 1].

numpy.bincount(x)です。行番号ごとに、非ゼロの要素がどのように返されますか。

numpy.bincount(x,wights=z)は、各行に対して、非ゼロ要素の合計を返します。

最終作業コード:

from scipy.sparse import csr_matrix 
a = csr_matrix([[0, 0, 2], [1, 3, 8]]) 

import numpy 
import scipy.sparse 
(x,y,z)=scipy.sparse.find(a) 
countings=numpy.bincount(x) 
sums=numpy.bincount(x,weights=z) 
averages=sums/countings 

print(averages) 

リターン:CSR形式の行列で

[ 2. 4.] 
+0

優秀、ありがとう – batsc

5

は、あなたも、より簡単にこれを行うことができます。

sums = a.sum(axis=1).A1 
counts = np.diff(a.indptr) 
averages = sums/counts 

行-和があります直接サポートされており、CSR形式の構造は、の連続する値の差配列は、各行の非ゼロ要素の数に正確に対応します。

1

私はいつも興味のある軸の値を合計し、それぞれの行/列のゼロ以外の要素の合計で割っています。

ので、同様:

sp_arr = csr_matrix([[0, 0, 2], [1, 3, 8]]) 
col_avg = sp_arr.sum(0)/(sp_arr != 0).sum(0) 
row_avg = sp_arr.sum(1)/(sp_arr != 0).sum(1) 
print(col_avg) 
matrix([[ 1., 3., 5.]]) 
print(row_avg) 
matrix([[ 2.], 
     [ 4.]]) 

基本的には、特定の軸に沿ったすべてのエントリの合計値を合計するとTrueエントリの合計で割っているところ本当の数をある行列= 0(!エントリ)。

このアプローチは、他のオプションよりも複雑さが少なく、簡単です。

関連する問題