【问题标题】:Scipy Sparse Matrices - Inconsistent SumsScipy稀疏矩阵 - 不一致的和
【发布时间】:2012-11-04 08:10:12
【问题描述】:

我有一个稀疏矩阵,它是通过一堆复杂的计算得出的,在这里我无法重现。我会尝试找到一个更简单的例子。

现在,有没有人知道(甚至是远程)我可以拥有一个稀疏矩阵X 具有以下属性:

In [143]: X.sum(0).sum()
Out[143]: 131138

In [144]: X.sum()
Out[144]: 327746

In [145]: X.sum(1).sum()
Out[145]: 327746

In [146]: type(X)
Out[146]: scipy.sparse.csr.csr_matrix

我唯一的猜测是,如果我想正确地对列求和,我需要首先将矩阵转换为 csc——这是有道理的。虽然有人会认为 sparse 包会优雅地处理列总和(或引发错误),而不是仅仅给出错误的答案。

经过深思熟虑,我尝试了以下方法:

In [164]: X.tocsr().sum(0).sum()
Out[164]: 131138

In [165]: X.tocsc().sum(0).sum()
Out[165]: 131138

In [166]: X.tocoo().sum(0).sum()
Out[166]: 131138

In [167]: X.tolil().sum(0).sum()
Out[167]: 131138

In [168]: X.todok().sum(0).sum()
Out[168]: 131138

In [169]: X.shape
Out[169]: (196980, 43)

In [170]: X
Out[170]: 
<196980x43 sparse matrix of type '<type 'numpy.uint16'>'
        with 70875 stored elements in Compressed Sparse Row format>

In [172]: X.todense().sum(0)
Out[172]: 
matrix([[170726,   1041, 117398,   3526,  13202,   3585,   2355,   1895,   1392,   2189,   2070,   2603,   1676,    496,   1194,    933,    129,
            529,    544,    256,      7,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
              0,      0,      0,      0,      0,      0,      0,      0,      0]], dtype=uint64)

In [173]: X.sum(0)
Out[173]: 
matrix([[39654,  1041, 51862,  3526, 13202,  3585,  2355,  1895,  1392,  2189,  2070,  2603,  1676,   496,  1194,   933,   129,   529,   544,   256,
             7,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
             0,     0,     0]], dtype=uint16)

我应该添加更多上下文:矩阵只有非负条目(它们是计数)。特别是有两个稀疏计数矩阵AB,我将它们相乘得到X

【问题讨论】:

  • 这里似乎有些不对劲...
  • 也许 scipy 邮件列表 更适合这样的问题?对我来说听起来像是一个错误。 您希望在这里得到什么答案
  • 好的——将尝试邮件列表。不确定是否还有其他我遗漏的东西。而且——如果有人对这如何可能有任何见解(以及我可能做出的错误假设)——那就太棒了。
  • 我认为您使用 uint16 和溢出的事实可能会影响它。其实这就是它的全部内容......
  • @gabe 是的,问题是,numpy 默默地向上转换到 uint32 的 sum 方法,稀疏矩阵没有。您可以计算出% 2**16 正是您所看到的...

标签: python numpy scipy sparse-matrix


【解决方案1】:

好的,所以 seberg 回答了这个问题。非常感谢。加油!

他观察到数据类型 uint16 可能是个问题。果然 - uint16 的最大值约为 65,000,而我的总和要大得多,尽管我的个人数据点要小得多。

布丁中的证明:

In [184]: Y = sparse.csc_matrix(X,dtype=np.uint32)

In [185]: Y.sum(0).sum()
Out[185]: 327746

In [187]: Y.sum(0)
Out[187]: 
matrix([[170726,   1041, 117398,   3526,  13202,   3585,   2355,   1895,   1392,   2189,   2070,   2603,   1676,    496,   1194,    933,    129,
            529,    544,    256,      7,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
              0,      0,      0,      0,      0,      0,      0,      0,      0]], dtype=uint32)

这解释了不一致的总和,并通过更改数据类型来纠正问题。虽然,仍然存在一个持久性问题——如果我有一个包含所有小条目的矩阵,我希望能够为其使用更小的数据类型(以节省内存)。

这是一个单独但相关的问题:

在对稀疏矩阵的列求和时,有没有办法优雅地处理数值溢出问题?

【讨论】:

  • 别在意最后一个问题。我现在看到溢出错误实际上得到了优雅的处理:scipy 正确地对整个矩阵求和。
猜你喜欢
  • 1970-01-01
  • 2014-10-15
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 2017-03-31
  • 2023-04-10
  • 2017-07-21
  • 2011-11-28
相关资源
最近更新 更多