【问题标题】:Mean of non zero values in sparse matrix?稀疏矩阵中非零值的平均值?
【发布时间】:2015-12-14 11:21:25
【问题描述】:

我正在尝试计算稀疏行矩阵每一行中非零值的平均值。使用矩阵的均值方法不行:

>>> 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.])

谁能告诉我是否有更快的方法?

【问题讨论】:

    标签: python scipy sparse-matrix


    【解决方案1】:

    使用 CSR 格式矩阵,您可以更轻松地做到这一点:

    sums = a.sum(axis=1).A1
    counts = np.diff(a.indptr)
    averages = sums / counts
    

    直接支持行求和,CSR 格式的结构意味着indptr 数组中连续值之间的差异正好对应每行中非零元素的数量。

    【讨论】:

    • 避免除以零错误的最佳方法?我在除法之前添加了这个:counts[counts == 0] = 1 但不知道这是否是最佳选择。逻辑是,如果 counts 为 0,则 sum 在该位置也必须为 0。因此,如果我们想保持它为 0,那么除以什么都没关系。
    【解决方案2】:

    这似乎是您可以使用numpy.bincount. 的典型问题为此我使用了三个函数:

    (x,y,z)=scipy.sparse.find(a)
    

    返回稀疏矩阵的行(x)、列(y)和值(z)。例如,xarray([0, 1, 1, 1].

    numpy.bincount(x) 为每个行号返回你有多少非零元素。

    numpy.bincount(x,wights=z) 为每一行返回非零元素的总和。

    最终的工作代码:

    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)
    

    返回:

    [ 2.  4.]
    

    【讨论】:

      【解决方案3】:

      我总是喜欢将您感兴趣的任何轴上的值相加,然后除以相应行/列中非零元素的总数。

      像这样:

      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.]])
      

      基本上,您将沿给定轴的所有条目的总值相加,然后除以矩阵 != 0 的 True 条目的总和(这是实际条目的数量)。

      我发现这种方法比其他选项更简单、更简单。

      【讨论】:

      • 我也喜欢这种方法,赞成。一项改进是使用nnz 避免形成x != 0(可能是大/内存密集型)矩阵。
      【解决方案4】:

      返回平均值列表的简单方法:

      a.sum(axis=0) / a.getnnz(axis=0)
      

      假设您的矩阵中没有任何明确的零。 如果愿意,可以更改轴。

      【讨论】:

        猜你喜欢
        • 2021-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多