2012-03-22 19 views
4

私は大きな疎マトリックスを持っています。その疎行列のすべての要素に対してlog4を取りたいと思います。疎行列で対数関数をとる効率的な方法

numpy.log()を使用しようとしましたが、マトリックスでは機能しません。

また、行ごとに対数を取ることもできます。それから、古い列を新しい列で押しつぶす。

# Assume A is a sparse matrix (Linked List Format) with float values as data 
# It is only for one row 

import numpy as np 
c = np.log(A.getrow(0))/numpy.log(4) 
A[0, :] = c 

これは私が期待したほど速くはありませんでした。これを行うより速い方法がありますか?

答えて

0

私は非常に簡単な方法で解決すると思います。誰もすぐに答えられないことは非常に奇妙です。あなたが直接data属性変更することができます

# Let A be a COO_matrix 
import numpy as np 
from scipy.sparse import coo_matrix 
new_data = np.log(A.data+3)/np.log(4) #3 is not so important. It can be 1 too. 
A = coo_matrix((new_data, (A.row, A.col)), shape=A.shape) 
+4

数学的に正しくないので、誰もこの解を提案していません。 'log(x)'は 'log(x + 1)'と大きく異なることがあります! (例: 'log(0.000001)= -6'、' log(0.0000001 + 1 = 0とビット) ' –

+0

私はすべてのデータが正で、1より大きいとは言いませんでした。 – Thorn

+0

ここに3つ(または何か)を追加する理由は全くありません。なぜなら、 'A.data'のエントリのどれもが0にならないからです。もしif '1e-16'を追加すると' log(0) 'は決してとることはないが、はるかに少ないエラーしか導入されないという同じ効果を持つだろう:[適切なアイデンティティlog(x + eps)= log(x)+ log(1 + eps/a) 'であり、ここで導入されたエラーは次のとおりです。 'eps/a'がほぼ0であれば0に近いです。 – Dougal

2

:スパースフォーマットは(COO形式で有効です)の要素を繰り返した場合、これは正常に動作しないことを

>>> a = np.array([[5,0,0,0,0,0,0],[0,0,0,0,2,0,0]]) 
>>> coo = coo_matrix(a) 
>>> coo.data 
array([5, 2]) 
>>> coo.data = np.log(coo.data) 
>>> coo.data 
array([ 1.60943791, 0.69314718]) 
>>> coo.todense() 
matrix([[ 1.60943791, 0.  , 0.  , 0.  , 0.  , 
      0.  , 0.  ], 
     [ 0.  , 0.  , 0.  , 0.  , 0.69314718, 
      0.  , 0.  ]]) 

は注意を。個別にログを取得し、log(a) + log(b) != log(a + b)を取得します。この問題を回避するには、まずCSRまたはCSCに変換する(高速です)場合があります。

スパース行列が別の形式である場合は、チェックを追加する必要があります。そして、行列をインプレースで修正したくない場合は、回答で行ったのと同じように、新しいスパース行列を作成してください。3を追加しないでください。

+0

私のソリューションとあなたのソリューションの違いは何ですか?あなたは私の解決策であなたからコメントとして既に提案されている3は必要ではないということだけを提案します。 – Thorn

+0

@Thorn私は実際にあなたのソリューションを誤って読んでいました。(マトリックス全体に3を追加して、不必要なログアームを大量に実行していたと思いました)あなたは基本的に同じものなのです。 – Dougal

関連する問題