Python:将纳秒转换为DateTime64格式

4 投票
3 回答
4835 浏览
提问于 2025-04-17 21:01

我有一列以秒为单位的 timestamps(从午夜开始计算),精确到纳秒,比如 34200.934549345, 34205.735545344,这些数据在一个叫 df 的表格里。

这些 timestamps 都来自同一天 2011-01-10

我想把这些带有纳秒精度的秒数转换成 numpyDateTime64 格式。

我希望在我的 df 中看到这些转换后的数据。

2011-01-10 9:30:00.934549345
2011-01-10 9:30:05.735545344

我需要做的操作和这个 例子 中的解决方案完全一样。

这样做可以吗?

3 个回答

0

我可以用datetime.strptime这个构造函数来解析这个字符串,但我需要把字符串最后的三个字符去掉:

>>> ds
'2011-01-10 9:30:00.934549345'
>>> datetime.datetime.strptime(ds[:-3], '%Y-%m-%d %H:%M:%S.%f')
datetime.datetime(2011, 1, 10, 9, 30, 0, 934549)

看起来,允许的时间精度的最后一层是微秒,也就是一百万分之一秒,而根据定义,微秒必须是六位数字:

>>> datetime.datetime(2011, 1, 10, 9, 30, 0, 934549345)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: microsecond must be in 0..999999

因为你有的是纳秒的时间,如果想把它转换成Python的datetime对象,你就得牺牲掉那种精度,或者不得不自己想办法解决。

1

我使用了strptime()这个函数来处理包含小数秒的字符串,并把它转换成微秒。因为小数点后有多少位数并没有固定,所以我得考虑所有可能的情况。我使用的是Python 2.6.7版本,这个版本要求strptime函数只能用整数秒,字符串里不能有小数部分。如果我用的是2.7.6版本,就可以使用格式中的%f部分了。不过,我还是得确保小数秒部分只有6位数字。

import datetime DT
def mystrptime(self, val)
  vals = val.split('.')
  if len(vals) == 1:
    dt = DT.datetime.strptime(val, '%Y-%m-%d %H%M%S')
  else:
    nofrag, frag = vals
    length = len(frag)
    if length > 6:
      frag = frag[:5]
      length = len(frag) # This resets length to 6, but is not really needed
    while length < 6:
      frag = frag + '0'
      length += 1
    nofrag_dt = DT.datetime.strptime(nofrag, '%Y-%m-%d %H%M%S')
    dt = nofrag_dt.replace(microsecond=int(frag))
  return dt

一旦安装了Python 2.7.6或更高版本,就可以像下面这样使用%f选项:

import datetime DT
def mystrptime(self, val)
  vals = val.split('.')
  if len(vals) > 1:
    nofrag, frag = vals
    frag = frag[:5] # This works even if frag is < 6 characters
    val = '.'.join(nofrag, frag)
  dt = DT.datetime.strptime(val, '%Y-%m-%d %H%M%S.%f')
  return dt
5
> df = pd.DataFrame({'seconds_since_midnight': [34200.934549345, 34205.735545344]})
> df['actual_date'] = (df.seconds_since_midnight * 1e9).astype('timedelta64[ns]') + pd.to_datetime('2011-01-10')
> df
   seconds_since_midnight                   actual_date
0            34200.934549 2011-01-10 09:30:00.934549345
1            34205.735545 2011-01-10 09:30:05.735545344

[2 rows x 2 columns]

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

撰写回答