使用Pandas Resample结合线性插值处理非整点小时数据
解决Pandas非整点温度数据转整点线性插值问题
问题原因
你用的df.resample('60min').first().interpolate('linear')达不到预期,核心问题在于:
- Pandas默认的
resample('60min')采用label='right'和closed='right'规则,会把你的15:51数据归到16:00结束的区间,最终生成的索引是16:00、17:00…22:00,完全没包含你需要的15:00-21:00整点。 - 后续的插值只是在这些错位的区间索引之间计算,根本没针对目标整点填充数据。
正确解决方案
步骤1:预处理数据(转换时间格式+设置索引)
首先要把时间列转为带时区的datetime类型,并设为DataFrame索引,确保时间计算准确:
import pandas as pd # 构造你的数据(实际场景可替换为读取文件) data = { 'Date Time, GMT-08:00': ['10/31/23 15:51', '10/31/23 16:51', '10/31/23 17:51', '10/31/23 18:51', '10/31/23 19:51', '10/31/23 20:51', '10/31/23 21:51'], 'Temp, °C': [13.41, 7.49, 7.61, 7.39, 7.34, 7.33, 7.38] } df = pd.DataFrame(data) # 转换为带GMT-08:00时区的datetime,设置为索引 df['Date Time, GMT-08:00'] = pd.to_datetime(df['Date Time, GMT-08:00'], format='%m/%d/%y %H:%M').dt.tz_localize('Etc/GMT+8') df = df.set_index('Date Time, GMT-08:00')
步骤2:生成目标整点索引并插值
方法一:直接生成目标整点时间序列,重索引后插值
如果需要包含原数据范围外的整点(比如15:00,早于第一个采样点15:51),需添加limit_direction='both'参数实现双向插值:
# 生成15:00到21:00的整点时间序列(匹配你的数据范围) target_hours = pd.date_range( start='2023-10-31 15:00:00', end='2023-10-31 21:00:00', freq='60min', tz='Etc/GMT+8' ) # 合并原时间点和目标整点,重索引后线性插值,最后提取整点数据 interpolated_df = df.reindex(df.index.union(target_hours)).interpolate(method='linear', limit_direction='both').loc[target_hours]
方法二:先补全所有时间点再插值提取
如果需要保留原采样点同时生成整点数据,可采用这种方式:
# 生成包含原时间点和所有整点的完整时间序列 all_times = df.index.union( pd.date_range( df.index.floor('H').min(), df.index.ceil('H').max(), freq='H', tz=df.index.tz ) ) # 重索引后线性插值,筛选出整点数据 df_full = df.reindex(all_times).interpolate(method='linear', limit_direction='both') result = df_full[df_full.index.minute == 0]
最终结果示例
执行后会得到如下整点温度数据(截取部分):
Temp, °C Date Time, GMT-08:00 2023-10-31 15:00:00 18.4420 2023-10-31 16:00:00 8.3785 2023-10-31 17:00:00 7.5732 ...
内容的提问来源于stack exchange,提问作者mitchute
相关产品推荐
相关产品推荐

