【问题标题】:Increasing value of top k elements in sparse matrix增加稀疏矩阵中前 k 个元素的值
【发布时间】:2014-07-21 14:50:28
【问题描述】:

我正在尝试找到一种有效的方法,让我将稀疏矩阵的前 k 个值增加某个常数值。我目前正在使用以下代码,这对于非常大的矩阵来说非常慢:

a = csr_matrix((2,2)) #just some sample data
a[1,1] = 3.
a[0,1] = 2.

y = a.tocoo()
idx = y.data.argsort()[::-1][:1] #k is 1
for i, j in izip(y.row[idx], y.col[idx]):
    a[i,j] += 1

实际上排序似乎很快,问题在于我的最后一个循环,我通过排序索引来增加值。希望有人知道如何加快速度。

【问题讨论】:

    标签: python sorting numpy scipy sparse-matrix


    【解决方案1】:

    您可以通过直接修改 a.data 而不是迭代行/列索引并修改单个元素来加快速度:

    idx = a.data.argsort()[::-1][:1] #k is 1
    a.data[idx] += 1
    

    这也节省了从 CSR --> COO 的转换。

    更新

    正如@WarrenWeckesser 正确指出的那样,由于您只对k 最大元素的索引感兴趣并且您不关心它们的顺序,因此您可以使用argpartition 而不是argsort。当a.data 很大时,这会快很多。

    例如:

    from scipy import sparse
    
    # a random sparse array with 1 million non-zero elements
    a = sparse.rand(10000, 10000, density=0.01, format='csr')
    
    # find the indices of the 100 largest non-zero elements
    k = 100
    
    # using argsort:
    %timeit a.data.argsort()[-k:]
    # 10 loops, best of 3: 135 ms per loop
    
    # using argpartition:
    %timeit a.data.argpartition(-k)[-k:]
    # 100 loops, best of 3: 13 ms per loop
    
    # test correctness:
    np.all(a.data[a.data.argsort()[-k:]] == 
           np.sort(a.data[a.data.argpartition(-k)[-k:]]))
    # True
    

    【讨论】:

    • 干杯,这项工作做得很好!
    • 因为只需要k 最大的元素,您可以使用arpartition 而不是argsort。如果a.data 很大,这可能会显着提高性能。
    • @WarrenWeckesser 很棒的建议 - 我已经用这两种方法的一些基准测试更新了我的答案
    猜你喜欢
    • 2021-03-11
    • 1970-01-01
    • 2019-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 2017-02-26
    • 2017-04-16
    相关资源
    最近更新 更多