【问题标题】:Fast way to create incidence matrix from list of label python?从标签python列表创建关联矩阵的快速方法?
【发布时间】:2021-03-29 16:07:58
【问题描述】:

我有一个数组y, len(y) = M,其中包含来自0 -> N 的值。例如,N = 3:

y = [0, 2, 0, 1, 2, 1, 0, 2]

发生矩阵A定义如下:

  • 尺寸MxM
  • A(i,j) = 1 if y(i) == y(j)
  • A(i,j) = 0 if y(i) != y(j)

一个简单的算法是:

def incidence(y):
    M = len(y)
    A = np.zeros((M,M))
    for i in range(M):
        for j in range(M):
            if y[i]==y[j]:
                A[i,j] = 1
    return A

但这很慢。有没有办法更快地做到这一点?例如,使用列表理解或向量化。

【问题讨论】:

    标签: python algorithm numpy cluster-analysis vectorization


    【解决方案1】:

    您可以通过简单地询问y 是否等于它的转置来利用 numpy 广播在我们的 python 上获得一些效率:

    import numpy as np
    
    y = np.array([1, 2, 1, 0, 0, 1, 2])
    
    def mat_me(y):
        return (y == y.reshape(-1, 1)).astype(int)
    
    mat_me(y)
    

    产生:

    array([[1, 0, 1, 0, 0, 1, 0],
           [0, 1, 0, 0, 0, 0, 1],
           [1, 0, 1, 0, 0, 1, 0],
           [0, 0, 0, 1, 1, 0, 0],
           [0, 0, 0, 1, 1, 0, 0],
           [1, 0, 1, 0, 0, 1, 0],
           [0, 1, 0, 0, 0, 0, 1]])
    

    比较:

    y = np.random.choice([1, 2, 3], size=3000)
    
    def mat_me_py(y):
        return (y == y.reshape([-1, 1])).astype(int)
    
    %timeit mat_me_py(y)  
    # 28.6 ms ± 1.11 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    

    对比

    y = np.random.choice([1, 2, 3], size=3000)
    y = list(y)
    
    def mat_me_py(y):
        return [[int(a == b) for a in y] for b in y]
    
    %timeit mat_me_py(y)
    # 4.16 s ± 213 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    在较大的列表中差异会变得非常明显。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-08
      • 1970-01-01
      • 1970-01-01
      • 2015-01-19
      • 1970-01-01
      • 1970-01-01
      • 2016-07-29
      相关资源
      最近更新 更多