我想写一个函数,将一个大型稀疏矩阵的行归一化(使它们的和为1)。
from pylab import *
import scipy.sparse as sp
def normalize(W):
z = W.sum(0)
z[z < 1e-6] = 1e-6
return W / z[None,:]
w = (rand(10,10)<0.1)*rand(10,10)
w = sp.csr_matrix(w)
w = normalize(w)
但是,这给出了以下例外情况:
File "/usr/lib/python2.6/dist-packages/scipy/sparse/base.py", line 325, in __div__
return self.__truediv__(other)
File "/usr/lib/python2.6/dist-packages/scipy/sparse/compressed.py", line 230, in __truediv__
raise NotImplementedError
有没有合理简单的解决方案?我已经看过this,但仍然不清楚如何实际做除法。
6条答案
按热度按时间xmjla07d1#
这已经在scikit-learn sklearn. preprocessing. normalize中实现了。
axis=1
应按行规范化,axis=0
按列规范化。使用可选参数copy=False
就地修改矩阵。nkkqxpd92#
虽然Aarons的答案是正确的,但当我想根据 absolute 值的最大值进行规范化时,我实现了一个解决方案,sklearn没有提供这个解决方案。我的方法使用非零项,并在csr_matrix.data数组中找到它们,以快速替换那里的值。
与sunan的解决方案相比,这种方法不需要将矩阵转换为密集格式(这可能会引起内存问题),也不需要矩阵乘法。我在形状为(35'000,486'000)的稀疏矩阵上测试了这种方法,耗时约18秒。
3z6pesqy3#
这是我解决办法。
mwg9r5ms4#
我发现这是一种优雅的方法,不需要使用内置函数。
vjrehmav5#
在不导入sklearn的情况下,转换为密集矩阵或乘法矩阵,并且通过利用csr矩阵的数据表示:
W.indices
是列索引的数组,W.data
是对应的非零值的数组,并且W.indptr
指向索引和数据中的行开始。如果需要L1范数,可以在求和时添加
numpy.abs()
,或者使用numpy.max()
按每行的最大值进行归一化。hc2pp10m6#
如果只使用csr_array,您可以使用它的
multiply
和sum
方法并执行以下操作: