首页 文章

Numpy / Scipy稀疏与密集乘法

提问于
浏览
3

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.]])

为什么稀疏矩阵可以解释为什么当正常矩阵不能时,数组应该被解释为列向量?

1 回答

  • 3

    spmatrix 类(你可以在scipy / sparse / base.py中查看) __mul__() 有一组"ifs"可以回答你的问题:

    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)
    

    对于一维数组,它总是从 compressed.py ,在类 _cs_matrix 内转到 _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]])
    

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

    对于1D矩阵,稀疏模块也不假设它适合列数 . 要检查您是否可以尝试:

    A * mat(vec)
    #ValueError: dimension mismatch
    

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

相关问题