2013-05-30 56 views
3

有似乎是SciPy的稀疏矩陣類型和正常numpy的矩陣型之間的一些差異numpy的/ SciPy的稀疏VS緻密乘法

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

爲什麼能稀疏矩陣制定出的陣列應當被解釋爲一列當正常矩陣不能時矢量?

+0

稀疏矩陣不是numpy矩陣的子類。這甚至不是「ndarray」。 – hpaulj

回答

3

spmatrix類(您可以在SciPy的/稀疏/ base.py選中)__mul__()有一組「如果」可以回答你的問題的:

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) 

對於一維數組它總是會去_mul_vector()compressed.py,裏面_cs_matrix類,下面給出代碼:

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將是唯一可行的選擇。

對於一維矩陣,稀疏模塊也不認爲它適合列數。要檢查,你可以嘗試:

A * mat(vec) 
#ValueError: dimension mismatch 

而且A * mat(vec).T將是你唯一的選擇。

+1

由於'快速路徑','A * vec'比'A * mvec'快,其中'mvec = mat(vec).T'。 – hpaulj