3. 多源传感器时间序列数据对齐与融合
任务目标
工业设备常部署多类传感器(如振动、温度、压力),各自采样频率不同(如10kHz、1Hz、0.5Hz)。本案例实现一个最小可复用的时间序列对齐与融合流程:读取多源CSV数据,按统一时间基准重采样对齐,输出单一特征矩阵供后续PHM建模使用。
环境依赖
Python 3.8+,需安装 pandas、numpy。无需其他第三方库。
输入数据格式
每个传感器一个CSV文件,包含两列:timestamp(Unix时间戳,秒级浮点数)和 value。示例数据文件:
vibration.csv— 采样频率10kHz(时间戳间隔0.0001s)temperature.csv— 采样频率1Hz(时间戳间隔1s)pressure.csv— 采样频率0.5Hz(时间戳间隔2s)
关键完整代码
import pandas as pd
import numpy as np
from pathlib import Path
def load_sensor_data(filepath):
"""读取传感器CSV,返回带datetime索引的Series"""
df = pd.read_csv(filepath)
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='s')
df = df.set_index('timestamp').sort_index()
# 去除重复时间戳,保留最后一个观测值
df = df[~df.index.duplicated(keep='last')]
return df['value']
def align_and_fuse(sensor_files, output_freq='1s'):
"""
将多个传感器文件按统一频率重采样对齐并融合
Parameters:
sensor_files: dict, {'传感器名': '文件路径'}
output_freq: str, 目标重采样频率(pandas频率别名)
Returns:
pd.DataFrame: 索引为统一时间轴,每列为一个传感器
"""
# 确定全局时间范围(所有传感器时间戳的最小~最大值)
all_timestamps = []
for path in sensor_files.values():
ts = pd.read_csv(path, usecols=['timestamp'])['timestamp']
all_timestamps.append(pd.to_datetime(ts, unit='s'))
global_start = min(ts.min() for ts in all_timestamps)
global_end = max(ts.max() for ts in all_timestamps)
# 生成统一时间轴
unified_index = pd.date_range(start=global_start, end=global_end, freq=output_freq)
fused_df = pd.DataFrame(index=unified_index)
for name, path in sensor_files.items():
series = load_sensor_data(path)
# 重采样到统一时间轴:先reindex到目标索引,再线性插值
aligned = series.reindex(unified_index.union(series.index)).sort_index()
aligned = aligned.interpolate(method='linear')
aligned = aligned.reindex(unified_index)
fused_df[name] = aligned.values
return fused_df
# ===== 最小调用入口 =====
if __name__ == '__main__':
# 假设当前目录下有这三个文件(可用下方代码生成模拟数据)
sensor_files = {
'vibration': 'vibration.csv',
'temperature': 'temperature.csv',
'pressure': 'pressure.csv'
}
# 若文件不存在,生成模拟数据用于演示
if not Path('vibration.csv').exists():
np.random.seed(42)
# 振动:10kHz,持续10秒
t_vib = np.arange(0, 10, 0.0001)
vib = 0.5*np.sin(2*np.pi*50*t_vib) + np.random.normal(0, 0.1, len(t_vib))
pd.DataFrame({'timestamp': t_vib, 'value': vib}).to_csv('vibration.csv', index=False)
# 温度:1Hz,持续10秒
t_temp = np.arange(0, 10, 1)
temp = 25 + 0.1*t_temp + np.random.normal(0, 0.05, len(t_temp))
pd.DataFrame({'timestamp': t_temp, 'value': temp}).to_csv('temperature.csv', index=False)
# 压力:0.5Hz,持续10秒
t_pres = np.arange(0, 10, 2)
pres = 100 + 0.5*np.sin(2*np.pi*0.2*t_pres)
pd.DataFrame({'timestamp': t_pres, 'value': pres}).to_csv('pressure.csv', index=False)
result = align_and_fuse(sensor_files, output_freq='1s')
print("融合后特征矩阵形状:", result.shape)
print(result.head())
# 保存结果
result.to_csv('fused_features.csv')
运行方式
- 将上述代码保存为
sensor_fusion.py; - 在代码所在目录执行
python sensor_fusion.py; - 若目录下无输入CSV,程序会自动生成10秒模拟数据并执行对齐融合。
验证方法与通过条件
- 输出检查:程序打印融合矩阵形状应为
(10, 3)(10秒数据按1s重采样,3个传感器列); - 时间轴验证:
result.index应为从第0秒到第9秒(或第10秒边界)的整秒时间戳,无缺失; - 数据完整性:
result.isnull().sum().sum()应为0,表示所有时间点均有融合值; - 数值合理性:
vibration列数值范围约在 [-1, 1] 内(因模拟信号幅值0.5加噪声),temperature约在 [25, 26] 内,pressure约在 [99.5, 100.5] 内; - 文件产物:当前目录生成
fused_features.csv,可用Excel或pandas打开检查每列数据随时间连续变化。
关键实现说明
对齐策略采用先合并索引再线性插值:将原始时间点与统一时间轴合并排序,插值后重采样回目标轴。该方法能正确处理传感器起始时间不一致的情况,且线性插值适用于缓慢变化的物理量(温度、压力);对于振动这类高频信号,1s重采样会丢失频域信息,实际PHM场景中应根据分析频带选择降采样频率或提取统计特征后再对齐。本案例聚焦对齐机制本身,特征提取不在范围内。