为什么使用Pandas.to_datetime进行日期转换比某些替代方案要慢得多?

时间:2013-10-31 10:43:53

标签: python pandas

执行性能分析,我非常惊讶地将pd.to_datetime视为性能的一大阻力(在我的用例中花费了91秒,耗费了91秒)。所以我可能没有像我应该那样使用这个功能。

简单示例,我需要以日期/时间戳格式转换timestamp = 623289600000000000L

import datetime
import time
import pandas as pd
timestamp = 623289600000000000L

timeit pd.to_datetime(timestamp, unit = 'ns')
10000 loops, best of 3: 46.9 us per loop

In [3]: timeit time.ctime(timestamp/10**9)
1000000 loops, best of 3: 904 ns per loop

timeit time.localtime(timestamp/10**9)
1000000 loops, best of 3: 1.13 us per loop

timeit datetime.datetime.fromtimestamp(timestamp/10**9)
1000000 loops, best of 3: 1.51 us per loop

timeit datetime.datetime.utcfromtimestamp(timestamp/10**9)
1000000 loops, best of 3: 1.29 us per loop

我知道这些函数每个返回一个不同的对象,但pd.to_datetime是迄今为止最慢的。这是预期的吗?

我现在在我的代码中使用datetime.datetime.utcfromtimestamp,它运行正常。但是,我宁愿继续使用熊猫。加上Pandas处理1970年以前的精美日期(见下文)。你能提供一些指导吗?

pd.to_datetime有一个优势:它支持负输入/ 1970-01-01之前的日期。这对我的用例来说也很重要。

timestamp =-445645400000000000L
pd.to_datetime(timestamp, unit = 'ns')
Timestamp('1955-11-18 01:36:40', tz=None)

datetime.datetime.utcfromtimestamp(timestamp/10**9)
Traceback (most recent call last):

  File "<ipython-input-9-99b040d30a3e>", line 1, in <module>
    datetime.datetime.utcfromtimestamp(timestamp/10**9)

ValueError: timestamp out of range for platform localtime()/gmtime() function

我在Windows 7上使用Python 2.7.5和Pandas 0.12.0。

3 个答案:

答案 0 :(得分:5)

to_datetime将以几种方式解析timestamp参数,以找出里面的时间戳。将表示datetime的字符串转换为Timestamp对象非常有用。

如果您正在操作的数据已经是时间戳int,则可以直接调用Timestamp对象来构建它:

pd.Timestamp(timestamp)
Out[51]: Timestamp('1989-10-02 00:00:00', tz=None)

%timeit pd.Timestamp(timestamp)
100000 loops, best of 3: 1.96 µs per loop

它也适用于负数:

pd.Timestamp(-445645400000000000L)
Out[54]: Timestamp('1955-11-18 01:36:40', tz=None)

答案 1 :(得分:4)

如果您要转换重复的日期时间值,使用以下函数在pandas中进行日期分析会使事情变得非常快。

基准:

$ python date-parse.py
to_datetime: 5799 ms
dateutil:    5162 ms
strptime:    1651 ms
manual:       242 ms
lookup:        32 ms

def lookup(s):
    """
    This is an extremely fast approach to datetime parsing.
    For large data, the same dates are often repeated. Rather than
    re-parse these, we store all unique dates, parse them, and
    use a lookup to convert all dates.
    """
    dates = {date:pd.to_datetime(date) for date in s.unique()}
    return s.apply(lambda v: dates[v])

而且,source.

答案 2 :(得分:1)

转换单个时间戳不是有效的比较,只是衡量函数调用的数量。

In [9]: arr = [timestamp] * 1000000

In [10]: %timeit pd.to_datetime(arr,unit='ns')
1 loops, best of 3: 234 ms per loop

In [12]: arr = (np.array(arr)/10**9).tolist()

In [13]: %timeit [ time.ctime(x) for x in arr ]
1 loops, best of 3: 1.6 s per loop

In [31]: f = datetime.datetime.utcfromtimestamp

In [32]: %timeit [ f(x) for x in arr ]
1 loops, best of 3: 643 ms per loop

很明显,当应用于非平凡的数据集时,使用矢量化方法会更快。