Python 3.x 稀疏矩阵的元素划分
我有一个大小为(nx m)的稀疏矩阵: 其中:Python 3.x 稀疏矩阵的元素划分,python-3.x,scipy,sparse-matrix,elementwise-operations,Python 3.x,Scipy,Sparse Matrix,Elementwise Operations,我有一个大小为(nx m)的稀疏矩阵: 其中: num_documents=n 词汇表大小=m 数据=标记化列表的列表 此外,我还有一个长度为n的列表: sums=sparse\u dtm.sum(1.tolist() 现在,我想做一个元素级除法,其中稀疏dtm中行I的每个单元格被总和[I]除法 使用传统Python元素划分的简单方法: In [192]: M.sum(1) Out[192]: matrix([[4], [2], [1]]) In [193]
- num_documents=n
- 词汇表大小=m
- 数据=标记化列表的列表
n
的列表:
sums=sparse\u dtm.sum(1.tolist()
现在,我想做一个元素级除法,其中稀疏dtm
中行I
的每个单元格被总和[I]
除法
使用传统Python元素划分的简单方法:
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. ]])
sparse\u dtm/sums
导致以下错误:
TypeError:/:“csr\u矩阵”和“列表”的操作数类型不受支持。
如何执行此元素除法?如果我理解正确,您需要将每行除以行的总和,对吗 在这种情况下,您需要重新调整总和
sparse_dtm / sparse_dtm.sum(1).reshape(-1, 1)
例如,您也可以使用pandas数据帧来执行此操作
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)
给予
然后将每行除以行的和
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
请注意,结果是密集的np.matrix
,而不是稀疏的
如果a行和为0,这可能会出现问题,但对于您的构造,这可能是不可能的
我们可以通过首先将和转换为稀疏来保留稀疏结果。我使用的是相反的,因为没有稀疏的元素划分(所有这些0):
谢谢Max,你的第一个建议很有效。但是,我使用的是稀疏矩阵,因为使用常规矩阵时会遇到内存问题。因此,熊猫的数据帧建议在我的情况下不起作用。
sparse\u dtm.sum(1)
应该已经是一个(n,1)形状的np.matrix
。无需重塑。@hpaulj withnp.ndarray
使用我定义的用于填充di nd数组的for循环,您的shapesparse\u dtm.shape
等于(10,5)
。如果你做了sparse\u dtm.sum(1)
你有一个形状sparse\u dtm.sum(1)
等于(10,)
,但是你需要一个(10,1)
的形状,正如你所说的,所以你必须重塑。重塑(-1,1)
对于密集数组,ndarray
你确实需要重塑,或者使用keepdims
。但是你继续称它为sparse\u dtm
,所以我假设它在OP创建时是scipy.sparse
。@hpaulj啊,是的,对不起,你说得对没有tolist
的sums
是什么?
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]])
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. ]])
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. ]])
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. ]])