稀疏矩阵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
  • 词汇_大小=m
  • data=标记化列表列表

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

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

现在,我想做一个元素分割,其中sparse_dtmrow_i的每个单元被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,0,2,0],[1,0,0,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, 1, 3, 0],
[0, 0, 2, 0],
[1, 0, 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.  , 0.  ],
[1.  , 0.  , 0.  , 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.25, 0.75, 0.  ],
[0.  , 0.  , 1.  , 0.  ],
[1.  , 0.  , 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.25, 0.75, 0.  ],
[0.  , 0.  , 1.  , 0.  ],
[1.  , 0.  , 0.  , 0.  ]])

最新更新