web-dev-qa-db-ja.com

日時の列をPythonでエポックに変換します

現在、Pythonで問題が発生しています。 Pandas DataFrameがあり、列の1つが日付の文字列です。形式は次のとおりです。

"%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")))

列全体をエポック時間に変換する方法を知っていますか?

前もって感謝します !

15
marcsarfa

_to_datetime_を使用して文字列を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
_

また、それが大幅に速いことがわかります

17
EdChum

時系列データの取り扱いについて Pandasのドキュメント から:

エポック(1970年1月1日の真夜中)を差し引き、次にフロアを「単位」(1 ms)で除算します。

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

これは、エポック時間をミリ秒単位で示します。

2
ares