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')

运行方式

  1. 将上述代码保存为 sensor_fusion.py;
  2. 在代码所在目录执行 python sensor_fusion.py;
  3. 若目录下无输入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场景中应根据分析频带选择降采样频率或提取统计特征后再对齐。本案例聚焦对齐机制本身,特征提取不在范围内。

多源传感器时间序列对齐融合流程 振动传感器 10kHz (0.0001s间隔) 温度传感器 1Hz (1s间隔) 压力传感器 0.5Hz (2s间隔) 对齐处理 ① 解析时间戳 → datetime索引 ② 确定全局时间范围 ③ 生成统一时间轴 (1s) ④ 重采样 + 线性插值 融合特征矩阵 时间轴 | 振动 | 温度 | 压力 10行 × 3列 无缺失值 插值方法:线性插值(适用于缓变信号);高频信号建议先提取统计特征再对齐