Каков идиоматический способ преобразования pandas DateTimeIndex в (iterable of) Unix Time? Вероятно, это не путь:
[time.mktime(t.timetuple()) for t in my_data_frame.index.to_pydatetime()]
Каков идиоматический способ преобразования pandas DateTimeIndex в (iterable of) Unix Time? Вероятно, это не путь:
[time.mktime(t.timetuple()) for t in my_data_frame.index.to_pydatetime()]
Поскольку DatetimeIndex
ndarray
под капотом, вы можете сделать преобразование без понимания (намного быстрее).
In [1]: import numpy as np
In [2]: import pandas as pd
In [3]: from datetime import datetime
In [4]: dates = [datetime(2012, 5, 1), datetime(2012, 5, 2), datetime(2012, 5, 3)]
...: index = pd.DatetimeIndex(dates)
...:
In [5]: index.astype(np.int64)
Out[5]: array([1335830400000000000, 1335916800000000000, 1336003200000000000],
dtype=int64)
In [6]: index.astype(np.int64) // 10**9
Out[6]: array([1335830400, 1335916800, 1336003200], dtype=int64)
%timeit [t.value // 10 ** 9 for t in index]
10000 loops, best of 3: 119 us per loop
%timeit index.astype(np.int64) // 10**9
100000 loops, best of 3: 18.4 us per loop
Примечание. Временная метка - это просто unix-время с наносекундами (поэтому разделите его на 10 ** 9):
[t.value // 10 ** 9 for t in tsframe.index]
Например:
In [1]: t = pd.Timestamp('2000-02-11 00:00:00')
In [2]: t
Out[2]: <Timestamp: 2000-02-11 00:00:00>
In [3]: t.value
Out[3]: 950227200000000000L
In [4]: time.mktime(t.timetuple())
Out[4]: 950227200.0
Поскольку @root указывает, что быстрее извлечь массив значений напрямую:
tsframe.index.astype(np.int64) // 10 ** 9
Краткое изложение других ответов:
df['<time_col>'].astype(np.int64) // 10**9
Если вы хотите сохранить миллисекунды, вместо этого делите на 10**6
В дополнение к другим ответам: //10**9
выполнит деление на пол, которое дает полные прошедшие секунды, а не ближайшее значение в секундах. Простой способ получить более разумное округление, если это желательно, состоит в том, чтобы добавить 5*10**8 - 1
перед выполнением деления на пол.
Чтобы рассмотреть случай NaT, который приведенные выше решения преобразуют в большие отрицательные целые числа, в pandas> = 0,24 возможное решение будет следующим:
def datetime_to_epoch(ser):
"""Don't convert NaT to large negative values."""
if ser.hasnans:
res = ser.dropna().astype('int64').astype('Int64').reindex(index=ser.index)
else:
res = ser.astype('int64')
return res // 10**9
В случае пропущенных значений возвращается тип int типа null 'Int64' (ExtensionType pd.Int64Dtype):
In [5]: dt = pd.to_datetime(pd.Series(["2019-08-21", "2018-07-28", np.nan]))
In [6]: datetime_to_epoch(dt)
Out[6]:
0 1566345600
1 1532736000
2 NaN
dtype: Int64
В противном случае обычный int64:
In [7]: datetime_to_epoch(dt[:2])
Out[7]:
0 1566345600
1 1532736000
dtype: int64
Если вы попытались это сделать в столбце datetime вашего фрейма данных:
dframe['datetime'].astype(np.int64) // 10**9
& амп; что вы боретесь со следующей ошибкой: TypeError: int() argument must be a string, a bytes-like object or a number, not 'Timestamp'
вы можете просто использовать эти две строки:
dframe.index = pd.DatetimeIndex(dframe['datetime'])
dframe['datetime']= dframe.index.astype(np.int64)// 10**9