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

时间:2015-07-15 21:13:55

标签: matrix scipy

我有一个计数的CSR矩阵(X_ngrams)。我想通过记录每个条目的商和行中的总和来构建稀疏的log-odds矩阵。这是我最好的镜头:

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。

2 个答案:

答案 0 :(得分:0)

您可以使用csr_matrix.nonzero方法获取非零元素的索引数组。

答案 1 :(得分:0)

据我所知,人们不能在CSR稀疏矩阵上应用任意函数进行元素计算。相反,您可以创建具有相同结构的新稀疏矩阵,并在稀疏数据上运行计算。下面是示例代码,演示如何计算每个元素与每行上各列之和的比率的log():

A

以下是结果示例,打印两个矩阵中每行的第一个元素:

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)

不快,但我认为它已经足够了。样本X_ngrams数据集有2,596,855个非零元素,形状=(2257,202262),在我5岁的macbook pro上创建新矩阵需要10.5秒。