是否有可能在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不能正常工作,但后来我找不到另一种有效计算规范的方法。一种可能的解决方案是计算:
norm(asarray(vector1.todense()))
然后它首先杀死了使用稀疏向量的目的。作为最后一种方法,我可以迭代矢量的每个元素并手动计算规范,但由于效率非常重要,我正在寻找更快更容易实现的东西。
提前感谢您的帮助!
编辑:我尝试了所有建议,最好的解决方案是:(vector1.data ** 2).sum()
来自Dougal的但是Cython解决方案也非常好,并且随着向量增长的元素数量不同而变得更好。谢谢大家的帮助!
答案 0 :(得分:1)
vector1.data
,手动计算规范非常简单。您还可以使用vector1.multiply(vector1)
加.sum
或vector1.dot(vector1.T)
之类的内容,但正如Dougal指出的那样,对于这种简单的情况,这可能会慢得多。答案 1 :(得分:1)
我在这里遇到了同样的问题,我在cython中实现了一个函数来提高这个简单操作的速度。我用4M稀疏的双倍向量和100k非零元素测试了它。使用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)
答案 2 :(得分:0)
我不认为你的初始化正在做你认为的那样。
要使规范正常工作,您需要一个正方形数组。如果你想制作一个有400万个元素的正方形数组,你想做
csr_matrix( (2000,2000), dtype=float64)