代码之家  ›  专栏  ›  技术社区  ›  muon

和使用索引列表对numpy矩阵的行进行分组

  •  1
  • muon  · 技术社区  · 8 年前

    使用索引列表和应用函数切片numpy数组,是否可以矢量化(或以非矢量化方式实现)?矢量化将是大型矩阵的理想选择

    import numpy as np
    index = [[1,3], [2,4,5]]
    a = np.array(
           [[ 3,  4,  6,  3],
            [ 0,  1,  2,  3],
            [ 4,  5,  6,  7],
            [ 8,  9, 10, 11],
            [12, 13, 14, 15],
            [1, 1,    4,  5]])
    

    index ,给出:

    np.array([[8, 10, 12, 14],
              [17, 19, 24, 37]])
    
    2 回复  |  直到 8 年前
        1
  •  5
  •   Divakar    8 年前

    方法#1: 这是一种几乎矢量化的方法-

    def sumrowsby_index(a, index):
        index_arr = np.concatenate(index)
        lens = np.array([len(i) for i in index])
        cut_idx = np.concatenate(([0], lens[:-1].cumsum() ))
        return np.add.reduceat(a[index_arr], cut_idx)
    

    lens 通过循环理解,但由于我们只是获得长度,并且不涉及计算,这一步不会对计时产生任何大的影响。

    样本运行-

    In [716]: a
    Out[716]: 
    array([[ 3,  4,  6,  3],
           [ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11],
           [12, 13, 14, 15],
           [ 1,  1,  4,  5]])
    
    In [717]: index
    Out[717]: [[1, 3], [2, 4, 5]]
    
    In [718]: sumrowsby_index(a, index)
    Out[718]: 
    array([[ 8, 10, 12, 14],
           [17, 19, 24, 27]])
    

    numpy.dot 为了实现这些总和减少,我们给出了另一种方法,如下所示-

    def sumrowsby_index_v2(a, index):
        lens = np.array([len(i) for i in index])
        id_ar = np.zeros((len(lens), a.shape[0]))
        c = np.concatenate(index)
        r = np.repeat(np.arange(len(index)), lens)    
        id_ar[r,c] = 1
        return id_ar.dot(a)
    
        2
  •  1
  •   Joe Iddon    8 年前

    list comprehension ...

    index list 在里面 index ,创建一个新列表 list rows 在里面 a indexes . 从这里,我们有一个 属于 numpy arrays 我们可以应用 sum() 努比 array 总和() 将返回新的 element 阵列

    np.array([sum([a[r] for r in i]) for i in index])
    

    array([[ 8, 10, 12, 14],
           [17, 19, 24, 27]])