为什么从np.datetime64到float和back的转换导致时差?

时间:2019-01-22 08:51:12

标签: python numpy

使用以下代码,在转换回np.datetime64之后,我得到了两个小时的时间差。

如何避免这种情况? (如果这应该是一个话题:我目前在中欧)

import pandas as pd
import numpy as np
import datetime

a = np.datetime64('2018-04-01T15:30:00').astype("float")
a
b = np.datetime64(datetime.datetime.fromtimestamp(a))
b

Out[18]: numpy.datetime64('2018-04-01T17:30:00.000000')

3 个答案:

答案 0 :(得分:2)

问题不在np.datetime64转换中,而在datetime.datetime.fromtimestamp中。

Since Numpy 1.11np.datetime64是时区幼稚的。它不再假设输入是本地时间,也不打印本地时间。

但是,datetime.datetime.fromtimestamp确实采用当地时间。来自docs

  

返回与POSIX时间戳相对应的本地日期和时间,例如time.time()返回的日期和时间。如果可选参数tz为None或未指定,则时间戳将转换为平台的本地日期和时间,并且返回的datetime对象是天真的。

您可以改用datetime.datetime.utcfromtimestamp

>>> a = np.datetime64('2018-04-01T15:30:00').astype("float")
>>> np.datetime64(datetime.datetime.utcfromtimestamp(a))
numpy.datetime64('2018-04-01T15:30:00.000000')

答案 1 :(得分:1)

https://github.com/numpy/numpy/issues/3290

  

从1.7开始,datetime64尝试通过以下方式处理时区:

     
      
  • 假定所有datetime64对象都位于UTC中
  •   
  • 解析ISO 8601字符串时应用时区偏移量
  •   
  • 在ISO字符串未指定TZ时应用区域设置时区偏移。
  •   
  • 在打印等时应用区域设置时区偏移。
  •   

https://stackoverflow.com/a/18817656/7583612

  

classmethod datetime.fromtimestamp(timestamp,tz = None)

     

返回与POSIX时间戳相对应的本地日期和时间,   如time.time()返回的。如果可选参数tz为None或   未指定,时间戳将转换为平台的本地日期   和时间,并且返回的datetime对象是天真的。

     

否则tz必须是tzinfo子类的实例,并且   时间戳转换为tz的时区。在这种情况下,结果是   相当于   tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo = tz))

答案 2 :(得分:1)

回顾一些笔记,我发现了以下内容:

import numpy
dt64 = numpy.datetime64( "2011-11-11 14:23:56" )

# dt64 is internally just some sort of int
#      it has no fields, and very little support in numpy

import datetime, time
dtdt = dt64.astype(datetime.datetime)         # <<<<<<<< use this!
dtdt.year
dtdt.month
dtdt.day

# to convert back:
dt64 = np.datetime64(dtdt)                    # <<<<<<<< use this too!
dt64.item().strftime("%Y%b%d")

datetime time 模块是普通的python模块:它们运行良好,具有许多字段,转换和支持。

datetime64 是内置在 numpy 中的未完全实现的子类型。它只是某种64位int(?)(也许是1970年以来的秒?)。 datetime64 datetime.datetime 完全不同。如果将 datetime64 转换为float并返回,则会失去很多精度(位),因此会出错。

(不是numpy的一部分)模块 datetime 也可以执行以下操作:

# timedelta()
delta = datetime.timedelta(days=11, hours=10, minutes=9, seconds=8)

delta                   # datetime.timedelta(11, 36548)     # (days,seconds)
delta.days
delta.seconds
delta.microseconds
delta.total_seconds()   # 986948.0

# arithmetic: +-*/
#   2 timedelta's
#   timedelta and datetime
now = datetime.datetime.now()
christmas = datetime.datetime(2019,12,25)
delta = christmas - now

所以让 numpy 有时将您的日期数据存储为datetime64,但是我建议not- numpy 模块 datetime 可以在datetime上工作-算术。