如何将含NaT的Pandas datetime Series转为保留空值的Int64纳秒时间戳
将带NaT的datetime Series转换为纳秒级Unix时间戳(Int64类型)
首先创建包含NaT的datetime类型Series:
import pandas as pd t = pd.date_range('2022-01-01', '2022-01-02', freq='4H').to_series('t') t.iat[2] = None
该Series的输出为:
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]
需求是将其转换为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
尝试过的无效方法
- 直接转换为Int64类型:
t.astype(pd.Int64Dtype()) # 报错:datetime64[ns] cannot be converted to IntegerDtype - 先转float再转Int64:
t.astype(float).astype(pd.Int64Dtype()) # 报错:Cannot cast DatetimeArray to dtype float64 - 使用
timestamp()方法:t.map(lambda t: t.timestamp()).astype(pd.Int64Dtype()) # 报错:NaTType does not support timestamp - 使用
map并忽略空值:t.map(lambda t: t.timestamp(), na_action='ignore').astype(pd.Int64Dtype()) # 报错:'values' contains non-numeric NA NaT
现有可行但不够优雅的方法
((t - pd.Timestamp(1970, 1, 1)).dt.total_seconds() * 1e09).astype(pd.Int64Dtype())
符合Pandas惯用风格的解决方案
利用Pandas datetime类型的.dt.asi8属性,它直接返回自Unix纪元(1970-01-01)以来的纳秒数整数,对于NaT会返回NaN,之后只需转换为支持空值的Int64Dtype即可:
t.dt.asi8.astype(pd.Int64Dtype())
执行后得到的结果完全符合预期输出,代码更简洁且符合Pandas的设计风格。
内容的提问来源于stack exchange,提问作者shadowtalker
相关产品推荐
相关产品推荐

