基于非均匀时间戳温度数据生成5分钟间隔均匀序列的实现
解决方案:时间序列重采样 + PIL平滑曲线绘制
一、生成5分钟间隔的温度序列
方法1:使用Pandas(简洁高效)
Pandas对时间序列处理天生友好,步骤如下:
- 将原始元组列表转换为DataFrame,设置时间戳为索引
- 按5分钟频率重采样,用线性插值填充缺失值(也可选择最近邻、二次插值等方式)
代码示例:
import pandas as pd import datetime # 原始数据示例 raw_data = [ (datetime.datetime(2022, 11, 30, 8, 25, 10, 261853), 19.82), (datetime.datetime(2022, 11, 30, 8, 27, 22, 479093), 20.01), (datetime.datetime(2022, 11, 30, 8, 27, 36, 984757), 19.96), (datetime.datetime(2022, 11, 30, 8, 36, 46, 651432), 21.25), (datetime.datetime(2022, 11, 30, 8, 41, 27, 230438), 21.42), (datetime.datetime(2022, 11, 30, 11, 57, 4, 689363), 17.8) ] # 转换为DataFrame并设置时间索引 df = pd.DataFrame(raw_data, columns=['timestamp', 'temperature']) df.set_index('timestamp', inplace=True) # 5分钟重采样+线性插值 resampled_df = df.resample('5T').interpolate(method='linear') # 转换为目标元组列表 result = list(zip(resampled_df.index.to_pydatetime(), resampled_df['temperature'].tolist()))
方法2:使用NumPy(轻量适配受限硬件)
如果硬件资源紧张,用NumPy手动处理更轻量化:
- 将时间戳转换为Unix时间戳数值(单位秒)
- 生成目标5分钟间隔的时间戳序列
- 用线性插值计算对应温度值
代码示例:
import numpy as np import datetime raw_data = [ (datetime.datetime(2022, 11, 30, 8, 25, 10, 261853), 19.82), (datetime.datetime(2022, 11, 30, 8, 27, 22, 479093), 20.01), (datetime.datetime(2022, 11, 30, 8, 27, 36, 984757), 19.96), (datetime.datetime(2022, 11, 30, 8, 36, 46, 651432), 21.25), (datetime.datetime(2022, 11, 30, 8, 41, 27, 230438), 21.42), (datetime.datetime(2022, 11, 30, 11, 57, 4, 689363), 17.8) ] # 拆分数据并转换为Unix时间戳 timestamps = np.array([dt.timestamp() for dt, temp in raw_data]) temperatures = np.array([temp for dt, temp in raw_data]) # 确定目标时间范围的首尾5分钟整点 start_dt = raw_data[0][0].replace(minute=(raw_data[0][0].minute // 5)*5, second=0, microsecond=0) end_dt = raw_data[-1][0].replace(minute=(raw_data[-1][0].minute // 5)*5, second=0, microsecond=0) # 生成5分钟间隔的时间戳序列(单位秒) target_timestamps = np.arange(start_dt.timestamp(), end_dt.timestamp() + 300, 300) # 线性插值计算温度 interpolated_temps = np.interp(target_timestamps, timestamps, temperatures) # 转换回datetime元组列表 result = [ (datetime.datetime.fromtimestamp(ts), temp) for ts, temp in zip(target_timestamps, interpolated_temps) ]
二、用PIL绘制平滑温度曲线
受限硬件上,通过插值生成更多中间点实现平滑曲线,简单易实现且效果稳定:
代码示例:
from PIL import Image, ImageDraw import numpy as np # 假设已得到重采样后的result列表 resampled_data = result # 画布参数 width = 800 height = 400 padding = 50 # 提取时间和温度数据 times = [dt for dt, temp in resampled_data] temps = [temp for dt, temp in resampled_data] # 计算坐标映射范围 min_temp = min(temps) max_temp = max(temps) temp_range = max_temp - min_temp if max_temp != min_temp else 1 # 时间转x轴坐标(首尾对齐画布边缘) x_start = padding x_end = width - padding x_step = (x_end - x_start) / (len(times) - 1) if len(times) > 1 else 0 # 温度转y轴坐标(温度越高y值越小,适配PIL左上角原点) y_start = height - padding y_end = padding # 生成基础坐标点 base_points = [] for i in range(len(times)): x = x_start + i * x_step y = y_start - ((temps[i] - min_temp) / temp_range) * (y_start - y_end) base_points.append((x, y)) # 生成平滑插值点(每两个基础点间插10个中间点) smooth_points = [] for i in range(len(base_points)-1): x1, y1 = base_points[i] x2, y2 = base_points[i+1] for t in np.linspace(0, 1, 10): x = x1 + t*(x2 - x1) y = y1 + t*(y2 - y1) smooth_points.append((int(round(x)), int(round(y)))) smooth_points.append((int(round(base_points[-1][0])), int(round(base_points[-1][1])))) # 创建画布并绘制 img = Image.new('RGB', (width, height), color='white') draw = ImageDraw.Draw(img) # 绘制平滑曲线 draw.line(smooth_points, fill='blue', width=2) # 可选:绘制坐标轴 draw.line([(padding, padding), (padding, height-padding)], fill='black', width=1) draw.line([(padding, height-padding), (width-padding, height-padding)], fill='black', width=1) # 保存或显示 img.save('temperature_curve.png')
硬件适配优化:
- 减少插值点数量(比如每间隔插5个点)
- 降低画布分辨率(如600x300)
- 仅使用线性插值,避免复杂计算
内容的提问来源于stack exchange,提问作者lowercasename
相关产品推荐
相关产品推荐

