稀疏矩阵中非零值的平均值?
Mean of non zero values in sparse matrix?
我正在尝试计算稀疏行矩阵每一行中非零值的平均值。使用矩阵的均值方法不这样做:
>>> from scipy.sparse import csr_matrix
>>> a = csr_matrix([[0, 0, 2], [1, 3, 8]])
>>> a.mean(axis=1)
matrix([[ 0.66666667],
[ 4. ]])
以下方法有效,但对于大型矩阵来说速度很慢:
>>> import numpy as np
>>> b = np.zeros(a.shape[0])
>>> for i in range(a.shape[0]):
... b[i] = a.getrow(i).data.mean()
...
>>> b
array([ 2., 4.])
谁能告诉我是否有更快的方法?
这似乎是您可以使用的典型问题 numpy.bincount.
为此,我使用了三个函数:
(x,y,z)=scipy.sparse.find(a)
稀疏矩阵的 returns 行 (x
)、列 (y
) 和值 (z
)。例如,x
是 array([0, 1, 1, 1].
numpy.bincount(x)
returns,对于每个行号,你有多少个非零元素。
numpy.bincount(x,wights=z)
returns,对于每一行,非零元素的总和。
最终工作代码:
from scipy.sparse import csr_matrix
a = csr_matrix([[0, 0, 2], [1, 3, 8]])
import numpy
import scipy.sparse
(x,y,z)=scipy.sparse.find(a)
countings=numpy.bincount(x)
sums=numpy.bincount(x,weights=z)
averages=sums/countings
print(averages)
returns:
[ 2. 4.]
有了 CSR 格式矩阵,您可以更轻松地做到这一点:
sums = a.sum(axis=1).A1
counts = np.diff(a.indptr)
averages = sums / counts
直接支持行求和,CSR 格式的结构意味着 indptr
数组中连续值之间的差异恰好对应于每行中非零元素的数量。
我总是喜欢将您感兴趣的任何轴上的值相加,然后除以相应 row/column 中非零元素的总数。
像这样:
sp_arr = csr_matrix([[0, 0, 2], [1, 3, 8]])
col_avg = sp_arr.sum(0) / (sp_arr != 0).sum(0)
row_avg = sp_arr.sum(1) / (sp_arr != 0).sum(1)
print(col_avg)
matrix([[ 1., 3., 5.]])
print(row_avg)
matrix([[ 2.],
[ 4.]])
基本上,您是对给定轴上所有条目的总值求和,然后除以 True
条目的总和,其中矩阵 != 0(这是实际条目的数量)。
我发现这种方法比其他方法简单易行。
一个简单的方法来return一个列表的平均值:
a.sum(axis=0) / a.getnnz(axis=0)
假设您的矩阵中没有任何明确的零。
如果愿意,请更改轴。
我正在尝试计算稀疏行矩阵每一行中非零值的平均值。使用矩阵的均值方法不这样做:
>>> from scipy.sparse import csr_matrix
>>> a = csr_matrix([[0, 0, 2], [1, 3, 8]])
>>> a.mean(axis=1)
matrix([[ 0.66666667],
[ 4. ]])
以下方法有效,但对于大型矩阵来说速度很慢:
>>> import numpy as np
>>> b = np.zeros(a.shape[0])
>>> for i in range(a.shape[0]):
... b[i] = a.getrow(i).data.mean()
...
>>> b
array([ 2., 4.])
谁能告诉我是否有更快的方法?
这似乎是您可以使用的典型问题 numpy.bincount.
为此,我使用了三个函数:
(x,y,z)=scipy.sparse.find(a)
稀疏矩阵的 returns 行 (x
)、列 (y
) 和值 (z
)。例如,x
是 array([0, 1, 1, 1].
numpy.bincount(x)
returns,对于每个行号,你有多少个非零元素。
numpy.bincount(x,wights=z)
returns,对于每一行,非零元素的总和。
最终工作代码:
from scipy.sparse import csr_matrix
a = csr_matrix([[0, 0, 2], [1, 3, 8]])
import numpy
import scipy.sparse
(x,y,z)=scipy.sparse.find(a)
countings=numpy.bincount(x)
sums=numpy.bincount(x,weights=z)
averages=sums/countings
print(averages)
returns:
[ 2. 4.]
有了 CSR 格式矩阵,您可以更轻松地做到这一点:
sums = a.sum(axis=1).A1
counts = np.diff(a.indptr)
averages = sums / counts
直接支持行求和,CSR 格式的结构意味着 indptr
数组中连续值之间的差异恰好对应于每行中非零元素的数量。
我总是喜欢将您感兴趣的任何轴上的值相加,然后除以相应 row/column 中非零元素的总数。
像这样:
sp_arr = csr_matrix([[0, 0, 2], [1, 3, 8]])
col_avg = sp_arr.sum(0) / (sp_arr != 0).sum(0)
row_avg = sp_arr.sum(1) / (sp_arr != 0).sum(1)
print(col_avg)
matrix([[ 1., 3., 5.]])
print(row_avg)
matrix([[ 2.],
[ 4.]])
基本上,您是对给定轴上所有条目的总值求和,然后除以 True
条目的总和,其中矩阵 != 0(这是实际条目的数量)。
我发现这种方法比其他方法简单易行。
一个简单的方法来return一个列表的平均值:
a.sum(axis=0) / a.getnnz(axis=0)
假设您的矩阵中没有任何明确的零。 如果愿意,请更改轴。