Python:稀疏非方矩阵的L1范数

时间:2014-11-06 13:59:46

标签: python matrix scipy sparse-matrix norm

在尝试计算稀疏矩阵的1范数时,我遇到了一个问题。我正在使用函数scipy.sparse.linalg.onenormest,但它给了我一个错误,因为操作符只能作用于方阵。

这是一个代码示例:

from scipy import sparse

row = array([0,2,2,0,1,2])
col = array([0,0,1,2,2,2])
data = array([1,2,3,4,5,6])

A = sparse.csc_matrix( (data,(row,col)), shape=(5,3) )

onenormest(A)

这是错误:

Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
  File "C:\Python27\lib\site-packages\scipy\sparse\linalg\_onenormest.py", line 76, in onenormest
    raise ValueError('expected the operator to act like a square matrix')
ValueError: expected the operator to act like a square matrix

如果我将A定义为方形矩阵,则运算符onenormest有效,但这不是我想要的。

任何人都知道如何计算稀疏非方阵的1范数?

2 个答案:

答案 0 :(得分:1)

我认为您需要numpy.linalg.norm代替

from numpy import linalg
from scipy import sparse


row = array([0,2,2,0,1,2])
col = array([0,0,1,2,2,2])
data = array([1,2,3,4,5,6])

A = sparse.csc_matrix( (data,(row,col)), shape=(5,3) )

print linalg.norm(A.todense(), ord=1) #15

调用A.data无效,因为稀疏矩阵对象的.data只是数据 - 它显示为向量。

如果您的稀疏矩阵很小,那么这很好。如果它很大,那么显然这是一个问题。在这种情况下,您可以编写自己的例程。

如果您只对L^1-norm感兴趣,并且无法投射到密集,那么您可以通过以下方式进行:

def sparseL1Norm = lambda A: max([numpy.abs(A).getcol(i).sum() for i in range(A.shape[1])])

答案 1 :(得分:1)

这会找到每列的L1范数:

from scipy import sparse
import numpy as np

row = np.array([0,2,2,0,1,2])
col = np.array([0,0,1,2,2,2])
data = np.array([1,2,3,-4,-5,-6]) # made negative to exercise abs
A = sparse.csc_matrix( (data,(row,col)), shape=(5,3) )
print(abs(A).sum(axis=0))

产量

[[ 3  3 15]]

然后你可以用max来找到矩阵的L1范数:

print(abs(A).sum(axis=0).max())
# 15

abs(A)是一个稀疏矩阵:

In [29]: abs(A)
Out[29]: 
<5x3 sparse matrix of type '<type 'numpy.int64'>'
    with 6 stored elements in Compressed Sparse Column format>

summax是稀疏矩阵的方法,因此abs(A).sum(axis=0).max()计算L1范数而不加密矩阵。

注意:大多数NumPy函数(例如np.abs)不适用于稀疏矩阵。虽然np.abs(A)返回正确的结果,但它通过间接路由到达那里。更直接的途径是使用调用abs(A)的{​​{1}}。 Thanks to pv.指出这一点。