稀疏矩阵python上的元素划分

问题描述

我有一个大小为 (n x m) 的稀疏矩阵:

sparse_dtm = dok_matrix((num_documents,vocabulary_size),dtype=np.float32)
        for doc_index,document in enumerate(data):
            document_counter = Counter(document)
            for word in set(document):
                sparse_dtm[doc_index,word_to_index[word]] = document_counter[word]

地点:

  • num_documents = n
  • vocabulary_size = m
  • data = 标记化列表的列表

另外,我有一个长度为 n 的列表:

sums = sparse_dtm.sum(1).tolist()

现在,我想做一个逐元素划分,其中 row_isparse_dtm 的每个单元格都被 sums[i] 划分。

一种天真的方法,使用传统的 Python 元素划分:

sparse_dtm / sums

导致以下错误

TypeError: unsupported operand type(s) for /: 'csr_matrix' and 'list'

如何执行这种逐元素划分?

解决方法

如果我理解正确,你需要将每一行除以行的总和,对吗?

在这种情况下,您需要重塑总和

sparse_dtm / sparse_dtm.sum(1).reshape(-1,1)

例如,您也可以使用 Pandas DataFrame 来实现

row_num = 10
col_num = 5
sparse_dtm = np.ndarray((row_num,col_num),dtype=np.float32)
for row in range(row_num):
    for col in range(col_num):
        value = (row+1) * (col+2)
        sparse_dtm[row,col] = value
df = pd.DataFrame(sparse_dtm)
print(df)

给予

      0     1     2     3     4
0   2.0   3.0   4.0   5.0   6.0
1   4.0   6.0   8.0  10.0  12.0
2   6.0   9.0  12.0  15.0  18.0
3   8.0  12.0  16.0  20.0  24.0
4  10.0  15.0  20.0  25.0  30.0
5  12.0  18.0  24.0  30.0  36.0
6  14.0  21.0  28.0  35.0  42.0
7  16.0  24.0  32.0  40.0  48.0
8  18.0  27.0  36.0  45.0  54.0
9  20.0  30.0  40.0  50.0  60.0

然后将每一行划分为行的总和

df / df.sum(axis=1).values.reshape(-1,1)

给予

     0     1    2     3    4
0  0.1  0.15  0.2  0.25  0.3
1  0.1  0.15  0.2  0.25  0.3
2  0.1  0.15  0.2  0.25  0.3
3  0.1  0.15  0.2  0.25  0.3
4  0.1  0.15  0.2  0.25  0.3
5  0.1  0.15  0.2  0.25  0.3
6  0.1  0.15  0.2  0.25  0.3
7  0.1  0.15  0.2  0.25  0.3
8  0.1  0.15  0.2  0.25  0.3
9  0.1  0.15  0.2  0.25  0.3
,
In [189]: M = sparse.dok_matrix([[0,1,3,0],[0,2,[1,0]])
In [190]: M
Out[190]: 
<3x4 sparse matrix of type '<class 'numpy.int64'>'
    with 4 stored elements in Dictionary Of Keys format>
In [191]: M.A
Out[191]: 
array([[0,0]])

sum(1) 产生一个 (3,1) np.matrix,可以直接在除法中使用:

In [192]: M.sum(1)
Out[192]: 
matrix([[4],[2],[1]])
In [193]: M/M.sum(1)
Out[193]: 
matrix([[0.,0.25,0.75,0.  ],[0.,0.,1.,[1.,0.  ]])

请注意,结果是密集的 np.matrix,而不是稀疏的。

如果行总和为 0,这可能会出现问题,但您的构造可能不太可能。

我们可以通过首先将总和转换为稀疏来保留稀疏结果。我正在使用逆,因为没有稀疏的元素除法(所有那些 0):

In [205]: D=sparse.csr_matrix(1/M.sum(1))
In [206]: D
Out[206]: 
<3x1 sparse matrix of type '<class 'numpy.float64'>'
    with 3 stored elements in Compressed Sparse Row format>
In [207]: D.A
Out[207]: 
array([[0.25],[0.5 ],[1.  ]])
In [208]: D.multiply(M)
Out[208]: 
<3x4 sparse matrix of type '<class 'numpy.float64'>'
    with 4 stored elements in Compressed Sparse Row format>
In [209]: _.A
Out[209]: 
array([[0.,0.  ]])

sklearn 还添加了一些稀疏矩阵实用程序

In [210]: from sklearn import preprocessing
In [211]: preprocessing.normalize(M,norm='l1',axis=1)
Out[211]: 
<3x4 sparse matrix of type '<class 'numpy.float64'>'
    with 4 stored elements in Compressed Sparse Row format>
In [212]: _.A
Out[212]: 
array([[0.,0.  ]])