熊猫时间戳与日期时间的性能缓慢
Posted
技术标签:
【中文标题】熊猫时间戳与日期时间的性能缓慢【英文标题】:Slow performance of pandas timestamp vs datetime 【发布时间】:2015-05-25 01:36:37 【问题描述】:我似乎在 pandas.Timestamp 与 python 常规 datetime() 对象上的算术运算性能出乎意料地慢。 下面是一个演示基准:
import datetime
import pandas
import numpy
# using datetime:
def test1():
d1 = datetime.datetime(2015, 3, 20, 10, 0, 0)
d2 = datetime.datetime(2015, 3, 20, 10, 0, 15)
delta = datetime.timedelta(minutes=30)
count = 0
for i in range(500000):
if d2 - d1 > delta:
count += 1
# using pandas:
def test2():
d1 = pandas.datetime(2015, 3, 20, 10, 0, 0)
d2 = pandas.datetime(2015, 3, 20, 10, 0, 15)
delta = pandas.Timedelta(minutes=30)
count = 0
for i in range(500000):
if d2 - d1 > delta:
count += 1
# using numpy
def test3():
d1 = numpy.datetime64('2015-03-20 10:00:00')
d2 = numpy.datetime64('2015-03-20 10:00:15')
delta = numpy.timedelta64(30, 'm')
count = 0
for i in range(500000):
if d2 - d1 > delta:
count += 1
time1 = datetime.datetime.now()
test1()
time2 = datetime.datetime.now()
test2()
time3 = datetime.datetime.now()
test3()
time4 = datetime.datetime.now()
print('DELTA test1: ' + str(time2-time1))
print('DELTA test2: ' + str(time3-time2))
print('DELTA test3: ' + str(time4-time3))
以及我机器上对应的结果(python3.3,pandas 0.15.2):
DELTA test1: 0:00:00.131698
DELTA test2: 0:00:10.034970
DELTA test3: 0:00:05.233389
这是预期的吗? 除了尽可能将代码切换到 Python 的默认日期时间实现之外,还有其他方法可以消除性能问题吗?
【问题讨论】:
集中我的问题:我知道 pandas 和 numpy 用于矢量化处理。 问题出在应用程序中执行矢量处理的部分和处理离散值/事件的部分之间的接口:如果提供 pandas 日期时间表示,离散处理代码会受到影响。跨度> 好的,在这种情况下,如果您的基准测试代表您的用例,那么绝对没有理由使用 numpy 或 pandas 日期时间。下面我构建了一个替代示例,展示了 pandas datetime 会更快的情况。当然,我不能确定它在多大程度上代表了您的用例。 另外,您可能会考虑发布实际代码的简化版本,并询问是否有人有加快速度的想法。人们通常更容易对这类问题给出具体而实用的答案。 【参考方案1】:我的机器上也有类似的结果:
$ python -mtimeit -s "from datetime import datetime, timedelta; d1, d2 = datetime(2015, 3, 20, 10, 0, 0), datetime(2015, 3, 20, 10, 0, 15); delta = timedelta(minutes=30)" "(d2 - d1) > delta"
10000000 loops, best of 3: 0.107 usec per loop
$ python -mtimeit -s "from numpy import datetime64, timedelta64; d1, d2 = datetime64('2015-03-20T10:00:00Z'), datetime64('2015-03-20T10:00:15Z'); delta = timedelta64(30, 'm')" "(d2 - d1) > delta"
100000 loops, best of 3: 5.35 usec per loop
$ python -mtimeit -s "from pandas import Timestamp, Timedelta; d1, d2 = Timestamp('2015-03-20T10:00:00Z'), Timestamp('2015-03-20T10:00:15Z'); delta = Timedelta(minutes=30)" "(d2 - d1) > delta"
10000 loops, best of 3: 19.9 usec per loop
datetime
比对应的 numpy
、pandas
类似物快几倍。
$ python -c "import numpy, pandas; print(numpy.__version__, pandas.__version__)"
('1.9.2', '0.15.2')
目前尚不清楚为什么差异如此之大。确实,numpy
、pandas
代码针对矢量化操作进行了优化。但不清楚为什么这些特定的标量操作要慢两个数量级,例如,显式时区的添加不会减慢datetime.datetime
代码:
$ python3 -mtimeit -s "from datetime import datetime, timedelta, timezone; d1, d2 = datetime(2015, 3, 20, 10, 0, 0, tzinfo=timezone.utc), datetime(2015, 3, 20, 10, 0, 15, tzinfo=timezone.utc); delta = timedelta(minutes=30)" "(d2 - d1) > delta"
10000000 loops, best of 3: 0.0939 usec per loop
要解决此问题,如果您不能使用矢量化操作,您可以尝试将原生日期/时间类型整体转换为更简单(更快)的类似物(例如,POSIX 时间戳表示为浮点数)。
【讨论】:
感谢 J.F 和 John 的回答。底线:pandas 用于批处理,python 用于离散。以上是关于熊猫时间戳与日期时间的性能缓慢的主要内容,如果未能解决你的问题,请参考以下文章