Numpy / Scipy稀疏与密集乘法

稀疏稀疏矩阵类型和普通numpy矩阵类型之间似乎存在差异

import scipy.sparse as sp
A = sp.dia_matrix(tri(3,4))
vec = array([1,2,3,4])

print A * vec                        #array([ 1.,  3.,  6.])

print A * (mat(vec).T)               #matrix([[ 1.],
                                     #        [ 3.],
                                     #        [ 6.]])

print A.todense() * vec              #ValueError: matrices are not aligned

print A.todense() * (mat(vec).T)     #matrix([[ 1.],
                                     #        [ 3.],
                                     #        [ 6.]])

为什么稀疏矩阵可以解决普通矩阵无法处理的问题,即应将数组解释为列向量?

解决方法:

在spmatrix类(您可以在scipy / sparse / base.py中进行检查)中,__ mul __()有一组“ if”可以回答您的问题:

class spmatrix(object):
    ...
    def __mul__(self, other):
        ...
        M,N = self.shape
        if other.__class__ is np.ndarray:
            # Fast path for the most common case
            if other.shape == (N,):
                return self._mul_vector(other)
            elif other.shape == (N, 1):
                return self._mul_vector(other.ravel()).reshape(M, 1)
            elif other.ndim == 2  and other.shape[0] == N:
                return self._mul_multivector(other)

对于一维数组,它将始终从_cs_matrix类中的compressed.py中转到_mul_vector(),并提供以下代码:

def _mul_vector(self, other):
    M,N = self.shape

    # output array
    result = np.zeros(M, dtype=upcast_char(self.dtype.char,
                                           other.dtype.char))

    # csr_matvec or csc_matvec
    fn = getattr(sparsetools,self.format + '_matvec')
    fn(M, N, self.indptr, self.indices, self.data, other, result)

    return result

注意,它假定输出的行数为稀疏矩阵的行.基本上,它将输入的1D数组视为适合稀疏数组的列数(不存在转置或非转置).但是对于具有ndim == 2的ndarray,它无法进行这种假设,因此,如果您尝试:

vec = np.array([[1,2,3,4],
                [1,2,3,4]])

* vec.T将是唯一可行的选择.

对于一维矩阵,稀疏模块也不假定其适合列数.要检查您可以尝试:

A * mat(vec)
#ValueError: dimension mismatch

A * mat(vec).T将是您唯一的选择.

上一篇:numpy中使用FFT的频率分辨率问题


下一篇:python-具有numpy的N * M * M张量的矢量化(部分)逆