【问题标题】:What is the correct way to add elements to a csr_matrix?将元素添加到 csr_matrix 的正确方法是什么?
【发布时间】:2016-11-09 12:44:36
【问题描述】:

我有一个 csr_matrix,假设我调用了:

import scipy.sparse as ss
mat = ss.csr.csr_matrix((50, 100))

现在我想修改这个矩阵上的一些值。我打电话:

mat[0,1]+=1

我得到:

SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.

我只需要在创建矩阵之后设置几个值(最后以矩阵的比例)。稍后我将只读取列或对整个矩阵进行元素操作(如.log1p()

这样做的正确方法是什么?目前我可以忽略警告,但可能有更好的方法,不会产生警告。

【问题讨论】:

  • CSR 和 CSC 是快速线性代数计算的首选格式。您通常将矩阵构建为 COO、LIL 或 DOK,仅将其转换为 CSC 或 CSR 一次,然后对其进行昂贵的数学运算。这将有助于更好地理解您的用例:您想对矩阵做什么?您是否需要在昂贵的操作之间添加新数据,或者可以在一开始就批量添加?
  • 已编辑,希望更清楚。
  • 创建一个COO matrix,向其中添加值,然后将其转换为 CSC 或 CSR 矩阵(如果您的操作有速度优势)。如果您所追求的只是元素操作,那么首席运营官可能会很好。如果要提取列选择 CSC,如果行 CSR。

标签: python scipy sparse-matrix


【解决方案1】:

您可以控制警告的出现。默认设置是在运行期间显示一次,然后保持沉默。您可以更改它以引发错误、完全静默或每次都发出警告。

创建稀疏矩阵的常用方法是创建 3 个coo 样式数组,其中所有值均非零。然后做一个coo矩阵,或者直接做csr(采用相同风格的输入)。

coo 格式没有索引,所以无论如何你不能做M[i,j]=1。但是csr 确实实现了它。我认为警告是为了阻止多个更改(在一个循环中)而不是一两个。

更改csr 矩阵的稀疏度需要重新计算整个属性集(数据和索引指针)。这就是它昂贵的原因。我还没有做计时,但它可能几乎和使阵列新鲜一样昂贵。

lil 应该更适合增量分配。它将数据保存在列表列表中,并且将值插入列表非常快。但是将csr 转换为lil 并返回需要时间,所以我不会只添加一些内容。

【讨论】:

  • 我不想改变警告的外观,我想把事情做对。目前我不要求改变稀疏性,但它似乎无论如何都会发生,我想知道为什么。
  • 某些形式的添加也会触发此警告。
  • 我明白了,但这是否就像我将整个矩阵重新格式化为不稀疏一样糟糕,或者它只是一个误报?按照你的建议制作 3 个向量实际上并不便宜,所以如果它不能让事情变得更好,我不想切换到那个。
  • 你是如何构造数组开始的?
【解决方案2】:

代替:

from scipy.sparse import csr_matrix

# Create sparse matrix.
graph = csr_matrix((10, 10))
# Change sparse matrix.
graph[(1, 1)] = 0      # --- SLOW --- ^1
# Do some calculations.
graph += graph

或者:

from scipy.sparse import lil_matrix

# Create sparse matrix.
graph = lil_matrix((10, 10))
# Change sparse matrix.
graph[(1, 1)] = 0
# Do some calculations.
graph += graph         # --- SLOW --- ^2

结合两者的优势:

from scipy.sparse import csr_matrix, lil_matrix

# Create sparse matrix.
graph = lil_matrix((10, 10))
# Change sparse matrix.
graph[(1, 1)] = 0
# Done with changes to graph. Convert to csr.
graph = csr_matrix(graph)
# Do some calculations.
graph += graph         

不要把“--- SLOW ---”当作一刀切的戒律!这只是一个警告,在某些数据集中,您应该意识到可能有更快、更有效的方法来做事。对于其他数据集,这只会使您的代码更难阅读和维护,而不会带来任何性能优势。

1:根据警告“慢”:

/venv/lib/python3.8/site-packages/scipy/sparse/_index.py:82: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.

2:根据docs 中的警告“慢”:

LIL 格式的缺点:
算术运算 LIL + LIL 很慢(考虑 CSR 或 CSC)

【讨论】:

  • 而且,是的,我意识到这是一篇旧帖子。然而,当我遇到同样的错误时,它没有得到回答,搜索引擎把我丢到了这里,所以我认为值得对发生的事情进行解释。
猜你喜欢
  • 2013-04-04
  • 2010-11-07
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 2020-08-14
  • 2019-04-06
相关资源
最近更新 更多