我有一个计数的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。
答案 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秒。