python – 通过重新排列行/列来“密集”非常大的稀疏矩阵

我有一个非常大的稀疏矩阵(240k * 4.5k,≤1%非零元素),我想通过重新排列其行和列来“密集”,使左上区域富集为非零元素尽可能多. (为了使其更易于管理和可视化评估.)我更喜欢scipy和相关工具来做到这一点.

>对于“手动”交换稀疏矩阵的行/列的解决方案已经提出了一个很好的建议here但是它没有涵盖在上层中识别要交换哪些行/列以获得最佳浓缩(密集块)的挑战左角.
>请注意,基于非零元素的数量对行/列进行简单排序并不能解决问题. (如果我采用例如具有最多元素的两行,则它们之间不一定存在任何重叠 – 即在哪些列中 – 是元素所在的位置.)
>我也对scipy.sparse中针对此任务的最佳稀疏矩阵表示感到好奇.

欢迎提出任何建议或具体实施方案.

最佳答案 看起来您已经可以交换保留稀疏性的行,因此缺少的部分是对行进行排序的算法.所以你需要一个能给你一个“左”分的功能.可行的启发式方法如下:

>首先得到一个非零元素的掩码(你不关心实际值,只关心它的非零元素).
>估算沿列轴的非零值的密度分布:

def density(row, window):
    padded = np.insert(row, 0, 0)
    cumsum = np.cumsum(padded) 
    return (cumsum[window:] - cumsum[:-window]) / window

>将左侧得分计算为具有最大左侧惩罚密度的列(从右侧看):

def leftness_score(row):
    n = len(a)
    window = n / 10   # 10 is a tuneable hyper parameter
    smoothness = 1    # another parameter to play with
    d = density(row)
    penalization = np.exp(-smoothness * np.arange(n))
    return n - (penalization * d).argmax()

只要该密度的最大值不太靠右,该算法就会给具有高密度值的行提供更高的分数.进一步采取的一些想法:改进密度估计,使用不同的惩罚函数(而不是neg exp),将参数拟合到反映预期排序的一些综合数据等.

点赞