Matrix 如何将函数应用于SciPy CSR稀疏矩阵的行?

Matrix 如何将函数应用于SciPy CSR稀疏矩阵的行?,matrix,scipy,Matrix,Scipy,我有一个CSR计数矩阵(X_ngrams)。我想建立一个稀疏的对数赔率矩阵,通过获取每个条目的商的对数和整行的总和。这是我最好的照片: log_odds = X_ngrams.asfptype() # convert the counts to floats row_sums = log_odds.sum(axis=1) # sum up each row log_odds.log1p() # take log of each element for ii

我有一个CSR计数矩阵(X_ngrams)。我想建立一个稀疏的对数赔率矩阵,通过获取每个条目的商的对数和整行的总和。这是我最好的照片:

log_odds = X_ngrams.asfptype()   # convert the counts to floats
row_sums = log_odds.sum(axis=1)  # sum up each row
log_odds.log1p()                 # take log of each element
for ii in xrange(row_sums.shape[0]):
    log_odds[ii,:].__add__(math.log(row_sums[ii,0]))
但这就产生了一个错误:

NotImplementedError: adding a nonzero scalar to a sparse matrix is not supported
因此,我的问题是:如何修改CSR的内容?我只想修改存在的元素


也欢迎采取其他办法。基本问题是根据存在元素的每一行的列和来修改CSR。

您可以使用该方法来获得非零元素的索引数组。

据我所知,不能对CSR稀疏矩阵应用任意函数进行元素计算。相反,您可以使用相同的结构创建一个新的稀疏矩阵,只需在稀疏数据上运行计算。下面是示例代码,它显示了如何计算每行各列中每个元素与总和之比的log()

X_ngrams.sort_indices()    # *MUST* have indices sorted for this to work!
row_sums =   np.squeeze(np.asarray(X_ngrams.sum(axis=1),dtype=np.float64))
rows,cols = X_ngrams.nonzero()
data = np.array( [ math.log(x/row_sums[rows[ii]]) for ii,x in   enumerate(X_ngrams.data)] )
new_odds = csr_matrix((data,X_ngrams.indices,X_ngrams.indptr),shape=X_ngrams.shape)
以下是结果示例,打印两个矩阵中每行的第一个元素:

          row_sum   Xngrams new_odds
[ 0][1439] 1063       20    -3.973118
[ 1][  13] 1677       18    -4.534390
[ 2][1439] 5323       68    -4.360285
[ 3][1439] 983        15    -4.182559
这并不快,但我想已经足够好了。样本X_ngrams数据集有2596855个非零元素,形状=(225720262),在我5岁的macbook pro上创建新矩阵需要10.5秒