将以01/01/0001为午夜的纪元转换为熊猫中的DateTime

时间:2020-07-21 12:24:45

标签: python pandas

我有一列带有一系列时间戳的列。本来我以为它们在Unix时间戳系统中,所以我使用以下代码将它们转换为日期时间。

big_frame['date'] = pd.to_datetime(big_frame['filename'],unit='s')

但是,它给了我奇怪的结果,所以我进行了更多研究,发现时间戳基本上是使用.net时代的,即午夜01/01/0001。因此,文件名是从那个纪元开始的秒数。如何将数据框中的列转换为正确的DateTime?

例如,如果我有这个

63730342900 

结果应该是

14/07/2020 17:01:40

编辑:

https://www.epochconverter.com/seconds-days-since-y0

这是我找到的唯一可以正确转换上述时间戳记的网站

下面是我要转换的列

0     63729045145
1     63729045145
2     63729045146
3     63729045146
4     63729045146
5     63729045147
6     63729045147
7     63729045147

2 个答案:

答案 0 :(得分:3)

01/01/0001似乎超出了datetime / timedelta类型的范围。我们可以像这样做一点破解:

ref_date = pd.to_datetime('14/07/2020 17:01:40')
ref_stamp = 63730342900


bigframe['date'] = pd.to_timedelta(big_frame['date'] - ref_stamp, unit='s') + ref_date

输出:

0   2020-06-29 16:32:25
1   2020-06-29 16:32:25
2   2020-06-29 16:32:26
3   2020-06-29 16:32:26
4   2020-06-29 16:32:26
5   2020-06-29 16:32:27
6   2020-06-29 16:32:27
7   2020-06-29 16:32:27
Name: date, dtype: datetime64[ns]

答案 1 :(得分:2)

尽管有一个可以接受的答案,但我敢于提出另一种解决方案,因为它不依赖于特定的参考值,因此可能更直观,更不易出错。这种方法还将适用于所有情况。

解决方案的背景

问题中的时间值为距DateTime.MinValue .NET时代的秒数,相当于0001年1月1日00:00:00.0000000 UTC。幸运的是,Python还具有datetime.min,它是最早可表示的datetime,并且与最小的.NET时期相同。

>>> datetime.datetime.min
Out: datetime.datetime(1, 1, 1, 0, 0)

>>> datetime.datetime.min.strftime("%d/%m/%Y %H:%M:%S")
Out: 01/01/1 00:00:00

解决方案

现在,我们可以使用datetime.min将.NET时代作为基线,而只需加上秒。我们还可以指定所需的输出格式。

import datetime
(datetime.datetime.min + datetime.timedelta(seconds=63730342900)).strftime("%d/%m/%Y %H:%M:%S")

哪个给我们正确的

14/07/2020 17:01:40

让我们扩展解决方案以涵盖问题中的熊猫DataFrame

import pandas as pd
import datetime
# Create the dataframe as in the question
df = pd.DataFrame([63730342900, 63729045145,
                   63729045145, 63729045146, 
                   63729045146, 63729045146, 
                   63729045147, 63729045147, 
                   63729045147], columns = ["datetime"])
# Apply the previous formula to every cell in the column using a lambda function
df["datetime"] = df["datetime"].apply(lambda seconds: (datetime.datetime.min + datetime.timedelta(seconds=seconds)).strftime("%d/%m/%Y %H:%M:%S"))

结果是格式良好的数据框

    datetime
0   14/07/2020 17:01:40
1   29/06/2020 16:32:25
2   29/06/2020 16:32:25
3   29/06/2020 16:32:26
4   29/06/2020 16:32:26
5   29/06/2020 16:32:26
6   29/06/2020 16:32:27
7   29/06/2020 16:32:27
8   29/06/2020 16:32:27

了解详情

当然,Python datetime也具有相反的值datetime.max

>>> datetime.datetime.max.strftime("%d/%m/%Y %H:%M:%S")
Out: 31/12/9999 23:59:59

通过堆栈溢出学习