列表理解用 0 替换数组中的前 n 项

List comprehension to replace the first n items in array with 0

我正在编写一个 jitted 函数来用 0 替换多维数组中的前 N ​​个元素。我会这样做很多很多次,所以速度很重要。 @njit 大大加快了它的速度,但我想知道是否有一种方法可以使用列表理解来摆脱 for 循环。这是否有助于提高效率?有什么建议吗?

 import numpy as np
 from numba import njit

 lengths=np.random.randint(0,365, size=20)

 @njit
 def availarray(lengths):
     out=1+np.zeros((365, len(lengths)))
     for i in range(int(len(lengths))):
         out[:int(lengths[i]), i]=0*int(lengths[i])
     return out

我使用以下方法将 运行 时间缩短了大约 30%:

def avail_array(lengths):
    out = np.zeros((365, len(lengths)))
    for i in range(int(len(lengths))):
        out[int(lengths[i]):, i] = 1
    return out
  • 您的版本:

    41 µs ± 734 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

  • 本版本:

    28.2 µs ± 353 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

这可能只是选择随机长度的一个怪癖,但至少不使用 0*len(lengths[i]) 并且使用 np.ones(...)np.zeros(...) 而不是 1 + np.zeros(...) 是一个好的开始。

总而言之:摆脱所有对 intlen 的调用;去掉乘以 0;高效地生成原始数组。

def availarray(lengths):
    out = np.ones((365, lengths.size))
    for i in range(lengths.size):
        out[:lengths[i], i] = 0
    return out

这将执行时间从 49 mks 缩短到 31.7 mks。

从零数组开始并用 1 填充它效果更好:

def availarray(lengths):
    out = np.zeros((365, lengths.size))
    for i in range(lengths.size):
        out[lengths[i]:, i] = 1
    return out

在我的例子中,这进一步将执行时间减少到 26.3 mks,加速了 46%。