按轴汇总 scipy 矩阵中的非零值
Summarize non-zero values in a scipy matrix by axis
我有这段代码来总结 scipy 稀疏 csr 矩阵的每一行:
count_list = dtm.toarray().sum(axis=0)
我如何才能将每一行 总结为好像 每个非零值都 = 1?
我可以将所有值 >0
替换为 1,然后使用与上面相同的代码。
我还可以遍历矩阵中的每一行并使用 Numpy 的 count_nonzero
.
count_list = [np.count_nonzero(v) for v in row.toarray() for row in dtm]
有没有更简单、更直接的方法(类似于第一个例子中的方法)?
假设您没有明确的零,这是
count_list = dtm.indptr[1:] - dtm.indptr[:-1]
例如:
In [34]: dtm = scipy.sparse.random(1000, 1000, format='csr')
In [35]: count_list_np = [np.count_nonzero(v) for row in dtm for v in row.toarray()]
In [36]: count_list = dtm.indptr[1:] - dtm.indptr[:-1]
In [37]: np.array_equal(count_list, count_list_np)
Out[37]: True
如果您确实有明确的零,只需先删除它们,使用 eliminate_zeros
:
dtm.eliminate_zeros()
count_list = dtm.indptr[1:] - dtm.indptr[:-1]
In [1]: from scipy import sparse
In [2]: M = sparse.random(10,10,.2, 'csr')
In [3]: M
Out[3]:
<10x10 sparse matrix of type '<class 'numpy.float64'>'
with 20 stored elements in Compressed Sparse Row format>
In [4]: M.astype(bool)
Out[4]:
<10x10 sparse matrix of type '<class 'numpy.bool_'>'
with 20 stored elements in Compressed Sparse Row format>
In [6]: M.astype(bool).sum(axis=0)
Out[6]: matrix([[0, 3, 4, 3, 1, 3, 1, 0, 2, 3]], dtype=int64)
将其与数组进行比较 - 转换为 0/1 整数
In [7]: M.astype(bool).astype(int).A
Out[7]:
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 1],
[0, 0, 1, 0, 0, 1, 0, 0, 0, 1],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 0, 0, 0]])
对照矩阵 nnz 检查总数:
In [8]: M.astype(bool).sum(axis=0).sum()
Out[8]: 20
对于axis=0
,求和是跨行的,每列一个值。对于跨列求和(每行一个值),请使用 axis=1)
:
In [13]: M.astype(bool).sum(axis=1)
Out[13]:
matrix([[0],
[4],
[2],
[2],
[3],
[1],
[4],
[1],
[1],
[2]])
这是一个 (n,1) 稠密矩阵。您可以使用 A1
制作一维数组:M.astype(bool).sum(axis=1).A1
当矩阵不是正方形时,区别更容易看出。
count_nonzero
可以对密集数组做同样的事情(但不是稀疏数组):
In [15]: np.count_nonzero(M.A,axis=1)
Out[15]: array([0, 4, 2, 2, 3, 1, 4, 1, 1, 2])
采用@fuglede's
indptr
方法:
In [18]: np.diff(M.indptr)
Out[18]: array([0, 4, 2, 2, 3, 1, 4, 1, 1, 2], dtype=int32)
我有这段代码来总结 scipy 稀疏 csr 矩阵的每一行:
count_list = dtm.toarray().sum(axis=0)
我如何才能将每一行 总结为好像 每个非零值都 = 1?
我可以将所有值 >0
替换为 1,然后使用与上面相同的代码。
我还可以遍历矩阵中的每一行并使用 Numpy 的 count_nonzero
.
count_list = [np.count_nonzero(v) for v in row.toarray() for row in dtm]
有没有更简单、更直接的方法(类似于第一个例子中的方法)?
假设您没有明确的零,这是
count_list = dtm.indptr[1:] - dtm.indptr[:-1]
例如:
In [34]: dtm = scipy.sparse.random(1000, 1000, format='csr')
In [35]: count_list_np = [np.count_nonzero(v) for row in dtm for v in row.toarray()]
In [36]: count_list = dtm.indptr[1:] - dtm.indptr[:-1]
In [37]: np.array_equal(count_list, count_list_np)
Out[37]: True
如果您确实有明确的零,只需先删除它们,使用 eliminate_zeros
:
dtm.eliminate_zeros()
count_list = dtm.indptr[1:] - dtm.indptr[:-1]
In [1]: from scipy import sparse
In [2]: M = sparse.random(10,10,.2, 'csr')
In [3]: M
Out[3]:
<10x10 sparse matrix of type '<class 'numpy.float64'>'
with 20 stored elements in Compressed Sparse Row format>
In [4]: M.astype(bool)
Out[4]:
<10x10 sparse matrix of type '<class 'numpy.bool_'>'
with 20 stored elements in Compressed Sparse Row format>
In [6]: M.astype(bool).sum(axis=0)
Out[6]: matrix([[0, 3, 4, 3, 1, 3, 1, 0, 2, 3]], dtype=int64)
将其与数组进行比较 - 转换为 0/1 整数
In [7]: M.astype(bool).astype(int).A
Out[7]:
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 1],
[0, 0, 1, 0, 0, 1, 0, 0, 0, 1],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 0, 0, 0]])
对照矩阵 nnz 检查总数:
In [8]: M.astype(bool).sum(axis=0).sum()
Out[8]: 20
对于axis=0
,求和是跨行的,每列一个值。对于跨列求和(每行一个值),请使用 axis=1)
:
In [13]: M.astype(bool).sum(axis=1)
Out[13]:
matrix([[0],
[4],
[2],
[2],
[3],
[1],
[4],
[1],
[1],
[2]])
这是一个 (n,1) 稠密矩阵。您可以使用 A1
制作一维数组:M.astype(bool).sum(axis=1).A1
当矩阵不是正方形时,区别更容易看出。
count_nonzero
可以对密集数组做同样的事情(但不是稀疏数组):
In [15]: np.count_nonzero(M.A,axis=1)
Out[15]: array([0, 4, 2, 2, 3, 1, 4, 1, 1, 2])
采用@fuglede's
indptr
方法:
In [18]: np.diff(M.indptr)
Out[18]: array([0, 4, 2, 2, 3, 1, 4, 1, 1, 2], dtype=int32)