稀疏矩阵的逐元素划分 python
Element-wise division on sparse matrix 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()
现在,我想进行逐元素除法,其中 sparse_dtm
中 row_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. ]])
我有一个大小为 (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()
现在,我想进行逐元素除法,其中 sparse_dtm
中 row_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. ]])