【问题标题】:How to efficiently select a submatrix with Python?如何使用 Python 有效地选择子矩阵?
【发布时间】:2014-02-17 05:29:15
【问题描述】:

我有一个大小为 nxn 的邻接矩阵(所以矩阵是对称的),我想选择一个大小为 mxm 的子矩阵,然后得到它的上三角形。目前,我这样做如下:

from numpy import *
am = array([array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], dtype=uint8),
 array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], dtype=uint8)])

w= (0, 1, 2, 5, 22) # select the window that consist of these nodes only
window = am[ix_(list(w),list(w))]
upper = [el for arr in [window[i][i+1:] for i in range(len(window)-1)] for el in arr]

但是我需要多次执行获取子矩阵+获取其上三角形的操作,目前这是我代码的瓶颈。

有什么办法可以加快速度吗?如果有办法直接获取子矩阵的上三角形,我也会很感激,因为我不需要完整的子矩阵。

【问题讨论】:

    标签: python performance numpy matrix graph


    【解决方案1】:

    这行得通:

    w = np.array((0, 1, 2, 5, 22))
    n = len(w)
    rang = np.arange(n, 0, -1)
    rows = np.repeat(w, rang)
    col_idx  = np.arange(n * (n + 1) // 2)
    delta = np.repeat(np.concatenate(([0], np.cumsum(rang[1:]))),
                      rang)
    col_idx -= delta
    cols = np.take(w, col_idx)
    

    现在:

    >>> rows
    array([ 0,  0,  0,  0,  0,  1,  1,  1,  1,  2,  2,  2,  5,  5, 22])
    >>> cols
    array([ 0,  1,  2,  5, 22,  1,  2,  5, 22,  2,  5, 22,  5, 22, 22])
    >>> am[rows, cols]
    array([0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8)
    

    【讨论】:

    • 感谢您的回答。我实际上只是意识到,而不是 adj。矩阵,我可以看看 adj.列出并从那里提取子矩阵。自调整以来。在我的情况下,矩阵非常稀疏(只有几个元素非零),它会加快速度。但是,我不知道如何从 adj 中提取子矩阵。列表而不是形容词。矩阵.. 我在这里发布了这个问题,以防您想看看:stackoverflow.com/questions/21833811/… 再次感谢。
    【解决方案2】:

    试试numpy.triu(上三角)和numpy.tril(下三角)。

    【讨论】:

    • 我之前尝试过 triu,但由于它返回的只有下三角形被清零的完整矩阵,所以我编写了自己的代码来获取上三角形(我需要一个扁平的上三角形列表三角形)。但是,即使我使用 triu;我需要先选择子矩阵。
    • 上三角形的所有元素都是非零的吗?
    • 它们可以是 0 或 1,但不一定都是非零。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    • 2016-10-01
    相关资源
    最近更新 更多