Python 为什么Pandas.to_datetime的日期转换比其他方法慢得多?
在执行性能评测时,我非常惊讶地发现pd.to_datetime对性能的影响很大(在我的用例中,91秒花费了62秒)。因此,我可能没有像应该的那样使用该函数 简单的例子,我需要以日期/时间戳格式转换Python 为什么Pandas.to_datetime的日期转换比其他方法慢得多?,python,pandas,Python,Pandas,在执行性能评测时,我非常惊讶地发现pd.to_datetime对性能的影响很大(在我的用例中,91秒花费了62秒)。因此,我可能没有像应该的那样使用该函数 简单的例子,我需要以日期/时间戳格式转换时间戳=62328960000000000L import datetime import time import pandas as pd timestamp = 623289600000000000L timeit pd.to_datetime(timestamp, unit = 'ns') 10
时间戳=62328960000000000L
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
,效果很好。然而,我宁愿继续使用熊猫。加上熊猫可以处理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
timestamp=-44545400000000000L
pd.to_datetime(时间戳,单位='ns')
时间戳('1955-11-18 01:36:40',tz=None)
datetime.datetime.utcfromtimestamp(timestamp/10**9)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
datetime.datetime.utcfromtimestamp(timestamp/10**9)
ValueError:platform localtime()/gmtime()函数的时间戳超出范围
我在Windows 7上使用Python 2.7.5和Pandas 0.12.0。to_datetime将以多种方式解析timestamp参数,以找出其中的时间戳。将表示日期时间的字符串转换为时间戳对象非常有用 如果正在处理的数据已经是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)
to_datetime将以多种方式解析timestamp参数,以找出其中的时间戳。将表示日期时间的字符串转换为时间戳对象非常有用 如果正在处理的数据已经是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)
转换单个时间戳不是有效的比较,只是函数调用数量的度量
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
显然,当应用于非平凡的数据集时,使用矢量化方法要快得多。转换单个时间戳不是有效的比较,而只是函数调用数量的度量
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
显然,当应用于非平凡数据集时,使用矢量化方法要快得多。如果要转换重复的datetime值,使用以下函数在pandas中进行Dateparsing会使事情变得非常快速 基准:
$ 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])
而且,如果要转换重复的datetime值,pandas中带有以下函数的Dateparsing会让事情变得非常快速 基准:
$ 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])
而且,Jeff,我不能使用矢量化方法:我将这些时间戳作为事件流按顺序接收。我执行的任务现在是7秒而不是62秒。另外,用户Boud建议我使用
pd.Timestamp
而不是pd.to\u datetime
。我现在执行同样的任务快了9倍,使用了一个更合适的函数:我认为值得问这个问题:-)Jeff,我不能使用矢量化的方法:我将这些时间戳作为事件流依次处理。我现在执行的任务是7秒而不是62秒。另外,用户Boud建议我使用pd.Timestamp
而不是pd.to\u datetime
。我现在执行同样的任务快了9倍,并且使用了一个更合适的函数:我认为值得问这个问题:-)pd.Timestamp
,我需要的函数。谢谢你,先生pd.Timestamp
,我需要的函数。谢谢你,先生!当心在基准源代码中,s=pd.Series(['01-31-2012']*100000)
,所以YMMV。在基准源代码中,s=pd.Series(['01-31-2012']*100000)
,所以YMMV。