将int64系列转换为datetime的最有效方法?

时间:2013-10-31 15:57:08

标签: python optimization pandas

设置场景:我有一个dtype int64的Series对象。我需要将这些转换为datetime对象,只包含日期(没有小时和秒)

到目前为止,我一直在努力...

foo.head()=

0    1382400000
1    1382400000
2    1382054400
3    1381708800
4    1380758400
Name: da_0, dtype: int64

此功能:

def convert_stamp_to_date(stamp):
    try:
        d = datetime.datetime.utcfromtimestamp(stamp)
    except:
        d = datetime.datetime.utcfromtimestamp(0)
    d = datetime.datetime(d.year, d.month, d.day)
    return d

当我处理相关系列时,我会打电话:

foo = foo.apply(lambda x: convert_stamp_to_date(x))

这给了我正确的解决方案:

0   2013-10-22 00:00:00
1   2013-10-22 00:00:00
2   2013-10-18 00:00:00
3   2013-10-14 00:00:00
4   2013-10-03 00:00:00
Name: da_0, dtype: datetime64[ns]

这给了我想要的东西,但是我发现它很慢(因为它应该是,对吧?因为它只是天真的工作方式)。

对于长度约为5000的小型Series对象,转换平均需要~27ms。不是 ...但是,我可以很容易地将Series对象扩展到数百万行。对于那些人,我看到转换时间进入1-2分钟范围。与我使用相同大小的Series和DataFrames做的其他事情相比,这似乎太慢了。

我的第一个想法是尝试使用np.vectorize伪向量化该函数。但是,这实际上使转换大约10倍

vconvert_stamp_to_date = np.vectorize(convert_stamp_to_date)
foo = foo.apply(lambda x: vconvert_stamp_to_date(x))

虽然这仍然给了我正确的答案,但它将较小的Series对象的转换时间增加到大约350ms,而对于我使用的较大系列,我必须从脚本中ctrl + c,因为它是花费太长时间。

将时间戳转换为日期时间对象对我来说似乎有点荒谬可能是我的程序的瓶颈:(我必须相信在某个地方有更有效的方法。有人可以指点我正确的方向?目前,我已经耗尽了所有的熊猫法术力。如果你一直读到这里,我非常感激。

谢谢。

1 个答案:

答案 0 :(得分:4)

这些看起来像纪元秒,所以只需使用pd.to_datetime

In [12]: arr = [1382400000] * 1000000

In [14]: pd.to_datetime(arr,unit='s')
Out[14]: 
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-10-22 00:00:00, ..., 2013-10-22 00:00:00]
Length: 1000000, Freq: None, Timezone: None

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