提问人:Emaad Shamsi 提问时间:7/13/2020 最后编辑:Emaad Shamsi 更新时间:7/13/2020 访问量:91
什么比 np.sum 和 numpy 布尔运算符更有效?
What is more efficient that np.sum and numpy boolean operators?
问:
我在快速运行代码时遇到了一些问题。
在我的代码上使用逐行分析器后,我发现以下行是我大部分效率低下的来源:
import numpy as np
import datetime
timestamps = np.array(timestamps)
mask = (minTime <= timestamps) & (timestamps <= maxTime)
count = np.sum(mask)
timestamps
以日期时间列表开头,并且是单个日期时间。minTime
时间戳的示例值:
minTime = datetime.datetime(2020, 5, 21, 2, 27, 26)
timestamps = [datetime.datetime(2020, 5, 21, 2, 27, 26), datetime.datetime(2020, 5, 21, 2, 27, 26),
datetime.datetime(2020, 5, 21, 2, 27, 26), datetime.datetime(2020, 5, 21, 2, 30, 55),
datetime.datetime(2020, 5, 21, 2, 30, 55), datetime.datetime(2020, 5, 21, 2, 30, 55),
datetime.datetime(2020, 5, 21, 2, 34, 26), datetime.datetime(2020, 5, 21, 2, 34, 26),
datetime.datetime(2020, 5, 21, 2, 34, 26), datetime.datetime(2020, 5, 21, 2, 39, 26),
datetime.datetime(2020, 5, 21, 2, 39, 26), datetime.datetime(2020, 5, 21, 2, 39, 26)]
有没有更有效的方法来重写上面的代码?
任何建议都是值得赞赏的。
答:
1赞
Paul H
7/13/2020
#1
看起来对象非常快。比标准库速度提高约 2 倍。熊猫在这里挣扎。如果您使用 pandas Timestamps 作为 Series 对象的索引并使用访问器,它比您在下面看到的要好一些。但并没有好到哪里去。numpy.datetime64
datetime
.loc
from datetime import datetime
import numpy
import pandas
py_dts = numpy.array([
datetime(2020, 5, 21, 2, 27, 26),
datetime(2020, 5, 21, 2, 27, 26),
datetime(2020, 5, 21, 2, 27, 26),
datetime(2020, 5, 21, 2, 30, 55),
datetime(2020, 5, 21, 2, 30, 55),
datetime(2020, 5, 21, 2, 30, 55),
datetime(2020, 5, 21, 2, 34, 26),
datetime(2020, 5, 21, 2, 34, 26),
datetime(2020, 5, 21, 2, 34, 26),
datetime(2020, 5, 21, 2, 39, 26),
datetime(2020, 5, 21, 2, 39, 26),
datetime(2020, 5, 21, 2, 39, 26)
])
min_pydt = datetime(2020, 5, 21, 2, 27, 26)
max_pydt = datetime(2020, 5, 21, 2, 39, 26)
min_npdt = numpy.datetime64(min_pydt)
max_npdt = numpy.datetime64(max_pydt)
min_pddt = pandas.Timestamp(min_pydt)
max_pddt = pandas.Timestamp(max_pydt)
np_64s = numpy.array([numpy.datetime64(d) for d in py_dts])
pd_tss = pandas.Series([pandas.Timestamp(d) for d in py_dts])
def counter(timestamps, mindt, maxdt):
return ((mindt <= timestamps) & (timestamps <= maxdt)).sum()
在 Jupyter 笔记本中,我做了:
%%timeit
counter(py_dts, min_pydt, max_pydt)
每个循环 17.4 μs ± 1.31 μs(平均±标准开发 7 次,每次 100000 个循环)
%%timeit
counter(np_64s, min_npdt, max_npdt)
每个循环 7.42 μs ± 102 ns(平均±标准开发 7 次,每次 100000 个循环)
%%timeit
counter(pd_tss, min_pddt, max_pddt)
每个循环 531 μs ± 2.99 μs(平均±标准开发,7 次运行,每次 1000 个循环)
评论
0赞
Emaad Shamsi
7/13/2020
嘿,谢谢你的回答。这是否意味着将我的日期时间值从标准日期时间转换为 np.datetime64 然后执行我的操作会更便宜?强制转换是否会在每个循环中增加我应该避免的额外操作?
1赞
Paul H
7/13/2020
@EmaadShamsi我提前完成了所有的选角。正如你在这里看到的,我没有安排选角的时间。包括强制转换在内的总运行时间将根据您拥有的数据量而有所不同,应根据具体情况进行评估
0赞
Emaad Shamsi
7/15/2020
我明白,它仍然非常有用的信息。我刚刚检查了一下,我实际上使用的是熊猫时间戳,而不是日期时间。如何将其转换为 DataFrame 中的 np.datetime64?另外,您是否知道一种比使用 numpy 库更有效的方法来计算两个语句是否都为真?
1赞
Paul H
7/15/2020
你试过@EmaadShamsi?numpy.datetime64(timestamp)
评论