如何对比含不同日期列的Pandas DataFrame数据?
如何用Pandas在同一时间轴上对比降雨量与水位数据?
当然可以解决这个问题!我经常帮人处理这种时间轴不对齐的多数据源可视化需求,核心就是先把两个DataFrame的时间轴统一对齐,再用共享x轴的子图来绘制,这样就能完美对比同一时间点的峰值了。下面是具体步骤:
1. 先把时间列转成datetime类型
这是最基础也最容易忽略的一步——如果你的时间数据是字符串格式,Pandas根本没法正确对齐时间轴。先把两个DataFrame的时间列转换成datetime类型:
import pandas as pd import matplotlib.pyplot as plt # 假设你的降雨量数据存在rain_df,含datetime和rainfall列;水位数据在water_df,含datetime和water_level列 rain_df['datetime'] = pd.to_datetime(rain_df['datetime']) water_df['datetime'] = pd.to_datetime(water_df['datetime'])
2. 对齐两个DataFrame的时间轴
根据你的数据特性,有两种常用的对齐方式:
方式一:重采样到统一频率(适合周期性采样数据)
如果你的降雨量和水位数据是按不同周期采样的(比如一个每分钟记录,一个每5分钟记录),可以把它们重采样到同一个时间频率,比如5分钟:
# 先将datetime设为索引 rain_df = rain_df.set_index('datetime').resample('5T').mean() # 5分钟重采样,取均值(也可以用sum/last,看数据类型) water_df = water_df.set_index('datetime').resample('5T').mean() # 合并成一个DataFrame,同时去掉缺失值 combined_df = pd.concat([rain_df, water_df], axis=1).dropna()
方式二:按最近时间匹配(适合不规则采样数据)
如果你的数据是事件触发式的(比如降雨只在下雨时记录,水位是定时记录),可以用merge_asof匹配最近的时间点,还能设置最大时间差避免错误匹配:
# merge_asof要求数据必须按时间排序 rain_df_sorted = rain_df.sort_values('datetime') water_df_sorted = water_df.sort_values('datetime') # 匹配最近的时间点,允许最大30秒的时间差(根据你的数据调整) combined_df = pd.merge_asof( rain_df_sorted, water_df_sorted, on='datetime', tolerance=pd.Timedelta('30s'), direction='nearest' )
3. 绘制共享x轴的子图
这一步的关键是设置sharex=True,让两个子图共享同一个x轴——这样缩放、平移时,两个图的时间轴会完全同步,再也不会出现偏移:
# 创建两个上下排列的子图,共享x轴 fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True) # 绘制降雨量 ax1.plot(combined_df['datetime'], combined_df['rainfall'], color='steelblue', label='降雨量') ax1.set_ylabel('降雨量 (mm)') ax1.legend() ax1.grid(alpha=0.3) # 绘制水位 ax2.plot(combined_df['datetime'], combined_df['water_level'], color='coral', label='水位') ax2.set_xlabel('时间') ax2.set_ylabel('水位 (m)') ax2.legend() ax2.grid(alpha=0.3) # 自动调整子图间距 plt.tight_layout() plt.show()
额外小技巧
- 如果合并后有缺失值,可以用时间插值填充:
combined_df.interpolate(method='time', inplace=True),让曲线更平滑。 - 如果你想突出峰值,可以在图上用
ax.scatter()标记出超过阈值的点,比如降雨量超过10mm的时刻。
内容的提问来源于stack exchange,提问作者aloevgaard
相关产品推荐
相关产品推荐

