在Python中将日期时间列转换为纪元

时间:2016-02-25 14:28:35

标签: python datetime pandas epoch

我目前遇到Python问题。我有一个Pandas DataFrame,其中一列是一个带日期的字符串。 格式为:

  

“%Y-%m-%d%H:%m:00.000”。例如:“2011-04-24 01:30:00.000”

我需要将整个列转换为整数。我试图运行这段代码,但它非常慢,我有几百万行。

    for i in range(calls.shape[0]):
        calls['dateint'][i] = int(time.mktime(time.strptime(calls.DATE[i], "%Y-%m-%d %H:%M:00.000")))

你们知道如何将整个列转换为纪元时间吗?

提前致谢!

4 个答案:

答案 0 :(得分:15)

使用datetime将字符串转换为to_datetime,然后减去日期时间1970-1-1并调用dt.total_seconds()

In [2]:
import pandas as pd
import datetime as dt
df = pd.DataFrame({'date':['2011-04-24 01:30:00.000']})
df

Out[2]:
                      date
0  2011-04-24 01:30:00.000

In [3]:
df['date'] = pd.to_datetime(df['date'])
df

Out[3]:
                 date
0 2011-04-24 01:30:00

In [6]:    
(df['date'] - dt.datetime(1970,1,1)).dt.total_seconds()

Out[6]:
0    1303608600
Name: date, dtype: float64

您可以看到将此值转换回来的时间相同:

In [8]:
pd.to_datetime(1303608600, unit='s')

Out[8]:
Timestamp('2011-04-24 01:30:00')

因此,您可以添加新列或覆盖:

In [9]:
df['epoch'] = (df['date'] - dt.datetime(1970,1,1)).dt.total_seconds()
df

Out[9]:
                 date       epoch
0 2011-04-24 01:30:00  1303608600

修改

@Jeff建议的更好的方法:

In [3]:
df['date'].astype('int64')//1e9

Out[3]:
0    1303608600
Name: date, dtype: float64

In [4]:
%timeit (df['date'] - dt.datetime(1970,1,1)).dt.total_seconds()
%timeit df['date'].astype('int64')//1e9

100 loops, best of 3: 1.72 ms per loop
1000 loops, best of 3: 275 µs per loop

您还可以看到它明显更快

答案 1 :(得分:0)

Pandas documentation开始使用时间序列数据:

  

我们减去纪元(世界标准时间1970年1月1日午夜),然后将底数除以“单位”(1毫秒)。

stamps = pd.date_range('2012-10-08 18:15:05', periods=4, freq='D')
(stamps - pd.Timestamp("1970-01-01")) // pd.Timedelta('1ms')

这将给出纪元时间(以毫秒为单位)。

答案 2 :(得分:0)

我知道这很老,但我相信最干净的方法是这样:

int(pd.Timestamp("20200918 20:30:05").value/1000000)

给出1600461005000,即上述日期的纪元。 .value属性是自历元以来的纳秒数,因此我们除以1e6得出毫秒数。如果要以秒为单位,则除以1e9。

答案 3 :(得分:0)

为了扩展 s5s 的答案,我认为代码可以进一步泛化以适应缺失数据(例如由 pd.NaT 表示)。在 Pandas 1.2.4 上测试,不适用于 Pandas < 1.0。

calls['DATE'].apply(lambda x: x.timestamp() if not pd.isna(x) else pd.NA).astype('Int64')

一些评论:

  • pd.isna() 将捕获 pd.NaT

  • lambda 表达式将 pd.NaT 转换为 pd.NA,这将是缺失数据的新表示

  • 最后,lambda 表达式的输出将是整数和 pd.NA 的混合,因此我们需要一个 Pandas ExtensionDtype,例如 Int64 来处理这个

示例输出:

0            <NA>
1            <NA>
2            <NA>
3            <NA>
4            <NA>
          ...
865    1619136000
866    1619136000
          ...
Name: DATE, Length: 870, dtype: Int64