matplotlib date2num转换timedelta的单位及双向转换差异疑问
问题
我在DataFrame中存储了一些timedelta数据,示例如下:
df.timedelta_last_nms[0:5] Out: 0 0 days 00:00:00 1 0 days 00:02:50 2 0 days 00:05:16 3 0 days 00:07:02 4 0 days 00:08:55 Name: timedelta_last_nms, dtype: timedelta64[ns]
将其作为x轴绘图时,刻度值约为10^12量级,推测是纳秒单位的timedelta。于是我尝试用matplotlib.dates.date2num将时间信息转换为数值:
import matplotlib.dates as mdates mdates.date2num(df.timedelta_last_nms[0:5]) Out: array([0. , 1.96759259, 3.65740741, 4.88425926, 6.19212963])
转换得到了标量数组,但单位不明确,数值量级约为1到1.5分钟。然而用num2date反向转换时:
mdates.num2date(mdates.date2num(df.timedelta_last_nms[0:5])) Out: [datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), datetime.datetime(1970, 1, 2, 23, 13, 20, tzinfo=datetime.timezone.utc), datetime.datetime(1970, 1, 4, 15, 46, 40, tzinfo=datetime.timezone.utc), datetime.datetime(1970, 1, 5, 21, 13, 20, tzinfo=datetime.timezone.utc), datetime.datetime(1970, 1, 7, 4, 36, 40, tzinfo=datetime.timezone.utc)]
这些数值被解析为天。请问为何这对互补函数的转换单位看似不同,以及date2num的实际单位是什么?
解答
1. date2num的实际单位
date2num的输出单位是天,以1970-01-01 00:00:00 UTC为时间零点,数值代表从该零点开始经过的总天数(浮点数,小数部分对应一天内的时间占比)。
比如你得到的1.96759259,对应的是1天加上0.96759259天:
- 0.96759259 × 24小时 ≈ 23.222小时
- 0.222小时 × 60分钟 ≈ 13.32分钟
- 0.32分钟 × 60秒 ≈ 19.2秒
最终对应1天23小时13分20秒,和num2date返回的1970-01-02 23:13:20完全匹配。
2. 转换单位看似不同的原因
你误解了date2num输出数值的量级:它的数值是天数,不是分钟。
当你传入timedelta对象时,date2num会自动将这个时间增量加到1970-01-01 00:00:00 UTC上,得到一个具体的datetime对象,再将其转换为以天为单位的数值。你看到的1.967不是1.967分钟,而是1.967天——这说明你的DataFrame中显示的0 days 00:02:50可能存在显示错误,实际对应的timedelta应该是1天23小时13分20秒,否则转换结果不会匹配反向解析的日期。
另外补充:直接用timedelta64[ns]作为matplotlib的x轴时,matplotlib会读取其原始的纳秒计数,所以刻度值是10^12量级;而date2num转换后将其映射为从epoch开始的天数,数值量级就变成了个位数或十位数(对应几天的时间跨度)。
内容的提问来源于stack exchange,提问作者Lepakk

