【问题标题】:optimizing code for traversing a matrix in python优化python中遍历矩阵的代码
【发布时间】:2015-07-21 15:00:53
【问题描述】:

我正在做一个聚类算法,其中我有一个包含 (m) 行和 (n) 个特征的数据集。我为数据集创建了一个 Jaccard 相似度矩阵,将我的数据集转换为 (m*m) 相似度矩阵。

创建相似矩阵后,我在矩阵上运行一定的逻辑来找到几个坐标。

我编写的逻辑实际上遍历了矩阵中的一半元素,但这需要大量时间。由于我是 python 新手,所以我的代码并没有太优化,而是直截了当。

请在下面找到我的代码:

    similarity_dict={}
for (i,j), value in np.ndenumerate(matrix_for_cluster):
    if value>threshold and j>=i:
        if i in similarity_dict:
            similarity_dict[i].append(j)
            if i<>j:
                if j in similarity_dict:
                    similarity_dict[j].append(i)
                else:
                    similarity_dict[j]=[i]                    
        else:  
            similarity_dict[i]=[j]


Matrix for cluster is the similarity matrix, If any of the element's value is greater than the threshold value then the element index is stored in a dictionary. 

我非常感谢任何关于优化代码的帮助

【问题讨论】:

  • 使用简单的y, x = np.where(matrix_for_cluster &gt; threshold) 怎么样?这将为您提供满足条件的yx 坐标向量。这是你想要的吗?
  • @imaluengo,感谢您的回复。但是我正在寻找的是对于特定行-例如,(0)我想获取所有y轴坐标,例如(1(0,0),5(0,5),7(0,7) ) 超过阈值并将其存储在键 (0) 下的字典中。同样,我想找到每一行的所有 y 轴坐标并将这些坐标存储在关键行号下。
  • @imaluengo,好的,如果我做类似 . np.where(matrix_for_cluster[i] > 0.4) 我将遍历每一行。
  • @Sam:你能提供一个示例输入和预期输出吗?我不明白你在用similarity_dict 做什么。首先你声明它为空,然后你尝试迭代它,使用你在第一个循环中所做的相同索引名称i(这是故意的吗?)然后你尝试分配你正在循环的那个键,一些值的j。但是字典是空的。然后你问similarity_dict[j] 一个显然不存在的键?我想你还没有在这里分享完整的 similarity_dict 故事。

标签: python matrix


【解决方案1】:

这应该做同样的事情,但可能会产生更少的 VM 操作:

for (i,j), value in np.ndenumerate(matrix_for_cluster):
    if value>threshold and j>=i:
        similarity_dict.setdefault(i,[]).append(j)
        if i != j:
           similarity_dict.setdefault(j,[]).append(i)

但总的来说,scipy 和 numpy(你已经在使用我看到了)在矩阵和类似的东西上具有更优化的相似性,如果你可以将所有工作保留在 num/scipy 的原生东西中,你会得到性能要好得多。

【讨论】:

    【解决方案2】:

    在我看来,您想要或正在尝试构建的东西看起来像一个图表。在这种情况下,您可以使用networkx 包:

    >>> sim_matrix
    array([[0, 1, 0, 2, 2],
           [1, 0, 2, 0, 1],
           [0, 2, 0, 1, 2],
           [2, 0, 1, 0, 0],
           [2, 1, 2, 0, 0]])
    >>> sim_matrix[sim_matrix < 2] = 0 # apply your threshold
    >>> sim_matrix
    array([[0, 0, 0, 2, 2],
           [0, 0, 2, 0, 0],
           [0, 2, 0, 0, 2],
           [2, 0, 0, 0, 0],
           [2, 0, 2, 0, 0]])
    

    sim_matrix 一个 numpy 数组:

    >>> import networkx as nx
    >>> graph = nx.Graph(sim_matrix)
    >>> graph.nodes()
    [0, 1, 2, 3, 4]
    >>> graph.edges(2)
    [(2, 1), (2, 4)]
    >>> graph.edges(4)
    [(4, 0), (4, 2)]
    

    在内部 networkx 与 python 字典一起使用,所以它几乎是你想要构建的,但已经为你构建了。

    注意:这将创建一个无向图。如果您希望它具有方向性,请将 nx.Graph 更改为 nx.DiGraph 行。

    编辑:更新示例以使 sim_matrix 实际上是一个对称矩阵(无向图)。

    查找有关 networkx 和 numpy here 的更多信息。

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 2019-12-16
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-27
      • 1970-01-01
      • 2020-03-23
      相关资源
      最近更新 更多