1

Pythonでスパースベクトルのノルムを効果的に取得することは可能ですか?

私は次のことを試しました:

from scipy import sparse
from numpy.linalg import norm

vector1 = sparse.csr_matrix([ 0 for i in xrange(4000000) ], dtype = float64)

#just to test I set a few points to a value higher than 0

vector1[ (0, 10) ] = 5
vector1[ (0, 1500) ] = 80
vector1[ (0, 2000000) ] = 6

n = norm(t1)

しかし、エラーが発生します:

ValueError: dimension mismatch

ノルム関数は配列でのみ機能するため、おそらくcsr_matrixが機能しないのはそのためですが、ノルムを効果的に計算する別の方法が見つかりませんでした。考えられる解決策の1つは、次のように計算することです。

norm(asarray(vector1.todense()))

しかし、最初はスパースベクトルを使用する目的が失われます。そして最後のアプローチとして、ベクトルの各要素を反復処理し、ノルムを手動で計算することができましたが、効率が非常に重要であるため、より速く、より簡単に実装できるものを探していました。

助けてくれてありがとう!

編集:私は提案されたすべてを試しました、そして最良の解決策は:

(vector1.data ** 2).sum()

ダガルから。しかし、Cythonのソリューションも非常に優れており、ベクトルがゼロとは異なる要素の数が増えるにつれて、より適切に機能します。助けてくれてありがとう!

4

3 に答える 3

1
  1. あなたがそのような要素を実際に初期化して設定していないことを願っています、それらの警告は理由のために出されます、そしてあなたがたくさんのリソースを残していることを証明する4Mの一時的なリスト;)。
  2. 基礎となるデータvector1.dataを直接使用するだけで、手作業でノルムを計算するのは非常に簡単です。vector1.multiply(vector1)plus.sumvector1.dot(vector1.T)Dougalが指摘したように、この単純なケースでははるかに遅くなる可能性があります。
  3. もっとやりたいと思いますが、ベクトルノルムだけが必要な場合は、スパース行列を通過することは多くの不必要な作業のように思えます。
于 2012-09-24T22:53:54.900 に答える
1

ここでも同じ問題が発生しました。この簡単な操作の速度を上げるために、cythonに関数を実装しました。私はそれを100kの非ゼロ要素を持つdoubleの4Mスパースベクトルでテストしました。sqrt(vector.multiply(vector).sum())を使用するメソッドは、874usと私の関数205usを使用しました。

# sparseLib.pyx
#cython: boundscheck=False
from cython.parallel cimport prange
from cython.view cimport array as cvarray

import numpy as np

from libc.math cimport sqrt

cpdef double sparseNorm2(double [:] data) nogil:
  cdef long i
  cdef double value = 0.0
  for i in xrange(data.shape[0]):
    value += data[i]*data[i]
  return sqrt(value)
于 2012-09-25T12:51:19.807 に答える
0

私はあなたの初期化があなたが思っていることをしているとは思わない。

ノルムが機能するには、正方形の配列が必要です。400万個の要素を持つ正方形の配列を作成しようとしている場合は、

csr_matrix( (2000,2000), dtype=float64)

scipyでの初期化に関する完全なドキュメント

于 2012-09-24T17:30:40.877 に答える