【问题标题】:numpy bincount sequential slices of arraynumpy bincount 数组的顺序切片
【发布时间】:2020-03-22 10:45:52
【问题描述】:

给定 numpy 行包含来自 range(n) 的数字, 我想应用以下转换:

[1 0 1 2] --> [[0 1 0] [1 1 0] [1 2 0] [1 2 1]]

我们只是遍历输入列表并对当前(包括)左侧的所有元素进行 bincount。

import numpy as np

n = 3
a = np.array([1, 0, 1, 2])
out = []
for i in range(a.shape[0]):
    out.append(np.bincount(a[:i+1], minlength=n))
out = np.array(out)

有什么办法可以加快速度吗?我想知道是否有可能完全摆脱该循环并仅使用矩阵魔法。

编辑: 谢谢,lbragile,提到列表推导。这不是我的意思。 (我不确定它是否渐近显着)。我正在考虑一些更复杂的事情,例如根据 bincount 操作在后台的工作方式重写它。

【问题讨论】:

  • 你能再解释一下转换吗?我不确定我是否理解正确。
  • 我同意 Alexander,您对转换的解释不清楚,因此如果我们不知道要优化什么,我们将无法帮助您优化。另外,您的代码运行不正常,除非您将 append() 作为定义的函数,否则它不应接受任何参数。
  • 在任何情况下,您始终可以使用列表推导而不是 for 循环进行优化。

标签: python numpy decision-tree


【解决方案1】:

你可以像这样使用 cumsum:

idx = [1,0,1,2]
np.identity(np.max(idx)+1,int)[idx].cumsum(0)

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

【讨论】:

    【解决方案2】:

    使用列表推导:

    fast_out = [np.bincount(a[:i+1], minlength=n) for i in range(a.shape[0])]
    print(fast_out)
    

    输出:

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

    使用以下代码来计时:

    import timeit
    
    def timer(code_to_test):
        elapsed_time = timeit.timeit(code_to_test, number=100)/100
        print(elapsed_time)
    
    your_code = """
    import numpy as np
    
    n = 3
    a = np.array([1, 0, 1, 2])
    out = []
    for i in range(a.shape[0]):
        out.append(np.bincount(a[:i+1], minlength=n))
    out = np.array(out)
    """
    
    list_comp_code = """
    import numpy as np
    
    n = 3
    a = np.array([1, 0, 1, 2])
    fast_out = [np.bincount(a[:i+1], minlength=n) for i in range(a.shape[0])]
    """
    
    timer(your_code) # 0.001330663086846471
    timer(list_comp_code) # 1.4601880684494972e-05
    

    因此,当平均超过 100 次试验时,列表理解方法的速度快了 91 倍以上

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多