首页 > 解决方案 > 加快列表理解

问题描述

我正在尝试创建一个循环遍历数组并创建新数组的函数。Usint timeit 我发现最慢的部分是循环 numpy 数组。由于我用作输入的数组往往很长,我想尽可能加快速度。

有没有办法让列表理解循环更快?我提供了一个函数来重新创建我的问题:

def get_days(year, month):
    months=np.array([31,28,31,30,31,30,31,31,30,31,30,31])
    if month==2:
        if (year%4==0 and year%100!=0) or (year%400==0):
            return 29
    return months[month-1]

这个数组需要产生更好的性能:

res=np.arange(20788, 20940)
np.array([np.min([x+datetime.fromtimestamp(20809*24*60*60).day-1, x+get_days(datetime.fromtimestamp(20809*24*60*60).year, datetime.fromtimestamp(20809*24*60*60).month)]) for x in res])

标签: pythonperformancenumpy

解决方案


不是使用带有循环的列表理解,而是使用 numpy 函数和向量化。

b = np.array([np.min([x+datetime.fromtimestamp(20809*24*60*60).day-1, 
                      x+get_days(datetime.fromtimestamp(20809*24*60*60).year,
                                 datetime.fromtimestamp(20809*24*60*60).month)]) 
             for x in res])

c = np.minimum(res+datetime.fromtimestamp(20809*24*60*60).day-1,
               res+get_days(datetime.fromtimestamp(20809*24*60*60).year,
                            datetime.fromtimestamp(20809*24*60*60).month))

b == c

输出:

array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True])

计时

%timeit b = np.array([np.min([x+datetime.fromtimestamp(20809*24*60*60).day-1, x+get_days(datetime.fromtimestamp(20809*24*60*60).year, datetime.fromtimestamp(20809*24*60*60).month)]) for x in res])

每个循环 1.99 毫秒 ± 33.4 微秒(平均值 ± 标准偏差。7 次运行,每次 100 次循环)

%timeit c = np.minimum(res+datetime.fromtimestamp(20809*24*60*60).day-1, res+get_days(datetime.fromtimestamp(20809*24*60*60).year, datetime.fromtimestamp(20809*24*60*60).month))

每个循环 10.5 µs ± 310 ns(平均值 ± 标准偏差。7 次运行,每次 100000 次循环)


推荐阅读