考虑一个包含一些空值的 datetime-dtype 系列:
import pandas as pd
t = pd.date_range('2022-01-01', '2022-01-02', freq='4H').to_series('t')
t.iat[2] = None
2022-01-01 00:00:00 2022-01-01 00:00:00
2022-01-01 04:00:00 2022-01-01 04:00:00
2022-01-01 08:00:00 NaT
2022-01-01 12:00:00 2022-01-01 12:00:00
2022-01-01 16:00:00 2022-01-01 16:00:00
2022-01-01 20:00:00 2022-01-01 20:00:00
2022-01-02 00:00:00 2022-01-02 00:00:00
Freq: 4H, dtype: datetime64[ns]
这个系列的
dtype
是<M8[ns]
。据我了解,这意味着底层数据在物理上存储为 64 位整数,表示自 Unix 时代开始以来的纳秒数 (numpy.datetime64
)。但是我不知道NaT
是如何表示的。
我想获得一个整数时间戳,表示自 Unix 纪元开始以来的纳秒数,在数据中有
NaT
的地方使用空值。因此,我似乎应该能够以某种方式检查时间戳数据类型的精度,提取原始秒数,然后根据需要放大或缩小以获得纳秒。
预期产出:
2022-01-01 00:00:00 1640995200000000000
2022-01-01 04:00:00 1641009600000000000
2022-01-01 08:00:00 <NA>
2022-01-01 12:00:00 1641038400000000000
2022-01-01 16:00:00 1641052800000000000
2022-01-01 20:00:00 1641067200000000000
2022-01-02 00:00:00 1641081600000000000
Freq: 4H, dtype: Int64
没用的东西:
t.astype(pd.Int64Dtype()) # datetime64[ns] cannot be converted to IntegerDtype`
t.astype(float).astype(pd.Int64Dtype()) # Cannot cast DatetimeArray to dtype float64
t.map(lambda t: t.timestamp()).astype(pd.Int64Dtype()) # NaTType does not support timestamp
t.map(lambda t: t.timestamp(), na_action='ignore').astype(pd.Int64Dtype()) # 'values' contains non-numeric NA NaT
值得注意的是
.timestamp
逻辑挂在 NaT
上,我不知道如何干净地转换为“null-aware”Int64Dtype
.
确实有效但非常丑陋的东西:
((t - pd.Timestamp(1970, 1, 1)).dt.total_seconds() * 1e09).astype(pd.Int64Dtype())
有惯用的方法吗?
编辑
我不认为有一个好的方法可以做到这一点。另一种方法:
>>> t.view(int).astype(pd.Int64Dtype()).replace(np.iinfo(np.int64).min, pd.NA)
0 1640995200000000000
1 1641009600000000000
2 <NA>
3 1641038400000000000
4 1641052800000000000
5 1641067200000000000
6 1641081600000000000
Name: t, dtype: Int64
我不清楚你的期望。也许你可以使用
numpy
:
ts = t.values.astype(float)
dti = pd.to_datetime(ts)
>>> ts
array([ 1.64099520e+18, 1.64100960e+18, -9.22337204e+18, 1.64103840e+18,
1.64105280e+18, 1.64106720e+18, 1.64108160e+18])
>>> dti
DatetimeIndex(['2022-01-01 00:00:00', '2022-01-01 04:00:00',
'NaT', '2022-01-01 12:00:00',
'2022-01-01 16:00:00', '2022-01-01 20:00:00',
'2022-01-02 00:00:00'],
dtype='datetime64[ns]', freq=None)
>>> t
0 2022-01-01 00:00:00
1 2022-01-01 04:00:00
2 NaT
3 2022-01-01 12:00:00
4 2022-01-01 16:00:00
5 2022-01-01 20:00:00
6 2022-01-02 00:00:00
Name: t, dtype: datetime64[ns]