python - 加快列表理解
问题描述
我正在尝试创建一个循环遍历数组并创建新数组的函数。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])
解决方案
不是使用带有循环的列表理解,而是使用 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 次循环)
推荐阅读
- c++ - 减少读取数据库所需的时间
- python-3.x - Selenium 返回过时的元素或 NoSuchElementError 尽管元素在页面上
- c# - 如何使用 System.Text.Json 将 JsonDocument 反序列化为 POCO
- ip - 将静态 IP 推送到 OpenVPN 客户端 - Proxmox
- laravel - Laravel 6 $request->file('myfile') 总是返回 null
- python - 如果我不将输入数据居中,为什么我的线性回归模型会失败?
- javascript - 我需要检查一个数字是否不是小数,我正在尝试使用 Number.isInteger() 但不起作用
- python - 熊猫数据框选择具有多列字符串条件的行
- c# - UnauthorizedAccessException 通过 FTP 下载 .exe 文件时
- salesforce - 使用 Apex 触发器更新相关记录