You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何绘制pd.cut生成的分箱时间数据?解决绘图溢出错误

问题描述

我有如下格式的时间序列数据:

LFrame  Date_Time   DoW run_time    az  el  distance    pass_ID SV_ID   Direction   PFD_Jy
0   3114360965  2023-03-29 17:25:20 Wednesday   62720.0 349.254117  12.199639   2.171043e+06    2023_03_29_154  154 SB  8.505332
1   3114360977  2023-03-29 17:25:21 Wednesday   62721.0 349.216316  12.294878   2.164688e+06    2023_03_29_154  154 SB  1085.548185
2   3114360988  2023-03-29 17:25:22 Wednesday   62722.0 349.178240  12.390492   2.158335e+06    2023_03_29_154  154 SB  515.828602
3   3114360999  2023-03-29 17:25:23 Wednesday   62723.0 349.139888  12.486484   2.151987e+06    2023_03_29_154  154 SB  344.120530
4   3114361010  2023-03-29 17:25:24 Wednesday   62724.0 349.101256  12.582857   2.145641e+06    2023_03_29_154  154 SB  37.207705

因为数据采样间隔为1秒,绘图过于密集,我用以下代码对时间列分箱并分组取均值:

binned = SV_pfd_data.groupby(pd.cut(SV_pfd_data.Date_Time, SV_pfd_data.shape[0]//5), as_index=True).mean() # ~1 min bins
binned = binned.reset_index()

得到的分箱数据如下:

Date_Time   LFrame  run_time    az  el  distance    SV_ID   PFD_Jy
0   (2023-03-29 17:25:19.408999936, 2023-03-29 17:...   3.114361e+09    62722.5 349.158693  12.438994   2.155165e+06    154.0   448.731927
1   (2023-03-29 17:25:25.008474624, 2023-03-29 17:...   3.114361e+09    62728.0 348.943580  12.972617   2.120295e+06    154.0   213.259464
2   (2023-03-29 17:25:30.016949248, 2023-03-29 17:...   3.114361e+09    62733.0 348.740192  13.468287   2.088688e+06    154.0   556.595627
3   (2023-03-29 17:25:35.025423616, 2023-03-29 17:...   3.114361e+09    62738.0 348.529055  13.974280   2.057173e+06    154.0   872.418091

注意:分箱后的时间精度高于微秒,暂不清楚原因

随后我使用以下matplotlib代码绘图时触发错误:

timeOnly = matdates.DateFormatter('%H:%M:%S')

fig, ax = plt.subplots(figsize=(10,5))
ax.plot_date(binned.Date_Time, binned.PFD_Jy,
       label=r"$\nu$=1611.1")
ax.set_ylabel("PFD [Jy]")
ax.set_xlabel("Date-time")
ax.set_xticklabels(SV_pfd_data.Date_Time, rotation = 65, fontsize=10)
ax.xaxis.set_major_formatter(timeOnly)

错误信息:

OverflowError: int too big to convert

请问如何解决该问题,成功绘制分箱后的时间数据?


解决方法

出现错误的核心原因:pd.cut对时间列分箱后生成的是区间类型(Interval),matplotlib的plot_date无法直接处理该类型;同时你误用了原数据的时间来设置分箱后图表的刻度标签,进一步引发问题。

步骤1:将分箱时间转换为可识别的时间戳

方案A:用pd.Grouper直接按时间间隔分箱(推荐)

这种方式更直观,直接指定分箱时长,避免生成区间类型:

# 按5秒间隔分箱取均值,可根据需求调整freq参数(如'1min'代表1分钟)
binned = SV_pfd_data.groupby(pd.Grouper(key='Date_Time', freq='5s')).mean().reset_index()

方案B:提取现有区间的中点作为时间戳

如果坚持使用原pd.cut逻辑,需将区间列转换为时间戳:

# 提取每个时间区间的中点,转为pandas时间戳
binned['Date_Time'] = binned['Date_Time'].apply(lambda x: x.mid)
# 确保列类型为datetime64
binned['Date_Time'] = pd.to_datetime(binned['Date_Time'])

步骤2:修正绘图代码的刻度设置

原代码中ax.set_xticklabels(SV_pfd_data.Date_Time)是错误的,应让matplotlib自动生成刻度后再格式化:

import matplotlib.dates as matdates
import matplotlib.pyplot as plt

timeOnly = matdates.DateFormatter('%H:%M:%S')

fig, ax = plt.subplots(figsize=(10,5))
# 此时Date_Time为时间戳类型,plot_date可正常处理
ax.plot_date(binned['Date_Time'], binned['PFD_Jy'], label=r"$\nu$=1611.1", linestyle='-')
ax.set_ylabel("PFD [Jy]")
ax.set_xlabel("Date-time")
# 自动生成刻度后格式化显示
ax.xaxis.set_major_formatter(timeOnly)
# 旋转刻度标签避免重叠
plt.xticks(rotation=65, fontsize=10)
ax.legend()
plt.tight_layout()
plt.show()

补充:解决分箱时间精度过高问题

pd.cut会根据原数据时间精度自动调整区间精度,若需控制精度,可在分箱前转换时间列精度:

# 将时间列精度调整为毫秒
SV_pfd_data['Date_Time'] = SV_pfd_data['Date_Time'].dt.round('ms')

内容的提问来源于stack exchange,提问作者earnric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 22:23:11