【问题标题】:Fast vectorized way to convert row vector to inptrs for sparse matrix?将行向量转换为稀疏矩阵的 inptrs 的快速向量化方法?
【发布时间】:2021-01-02 21:45:16
【问题描述】:

对于稀疏矩阵,我们通常传入列索引 (indices) 和一个索引indices 向量的indptr 向量,因此indices[indptr[i]:indptr[i+1]] 是稀疏矩阵中i 行的元素。

是否有一个快速的、矢量化的、最好是 numpy 的解决方案来转换连续的向量 在 Python 中将行索引转换为 indptr

例如,如果这是我的 rows 索引向量:[0,1,1,2,2,2,3,5]...

indptr 向量将是 [0,1,3,6,7,7,8],其中 7 重复,因为行向量缺少第 4 行。

我可以用一个简单的循环来做到这一点:

for i in range(len(rows)):
    indptr[rows[i]+1] += 1
    indptr=np.cumsum(indptr)

但我想知道是否有更快的矢量化方式来做到这一点?

【问题讨论】:

  • 在您的代码中,rows 是什么,indptr 的初始值是什么?不清楚[0,1,3,6,7,7,8]是如何从[0,1,1,2,2,2,3,5]构造的
  • @Ehsan rows 是数据的行索引,从上到下排序。因此,如果矩阵看起来像 [[1, 2], [3, 4]],则数据数组将为 [1, 2, 3, 4],行索引将为 [0, 0, 1, 1],并且列索引应该是 [0, 1, 0, 1]。转换为 indptrs 的行索引将为 [0, 2, 4]。
  • 请查看发布的答案是否是您想要的。如果是,请随意接受。如果没有,请详细说明您如何构造数组indptr

标签: python arrays numpy scipy sparse-matrix


【解决方案1】:

我认为您正在寻找的是:

np.bincount(rows).cumsum()
#[1 3 6 7 7 8]

如果矩阵底部有可能为空的行,只需将其作为参数添加到bincount(根据@CJR 的建议):

np.bincount(rows, minlength=num_rows).cumsum()
#[1 3 6 7 7 8]

您可能还想在前面插入一个0bincount 所做的是计算每个 bin/row 中的元素数量,然后 cumsum 将它们相加。这样,您也将包含丢失的箱/行。

插入 0 的最佳方法可能是这样:

np.bincount(np.array(rows)+1).cumsum()
#[0 1 3 6 7 7 8]

或者你可以直接通过:

np.insert(np.bincount(rows).cumsum(),0,0)
#[0 1 3 6 7 7 8]

【讨论】:

  • @narcissa 欢迎您。请查看stackoverflow.com/help/someone-answers,了解如何接受关于 SO 的答案。谢谢。
  • 确保将 bincount 中的 minlength 设置为矩阵中的 # 行,否则您将错过 indptr 数组末尾的空行。
【解决方案2】:

另一个想法是

n = len(rows)
indptr = np.searchsorted(rows, np.arange(-1,n), side='right')

不确定哪个更快/更好

【讨论】:

    猜你喜欢
    • 2020-02-28
    • 2018-05-10
    • 2014-10-30
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 2018-04-05
    • 2017-03-26
    • 2019-09-28
    相关资源
    最近更新 更多