如何用Pandas重采样、插值并合并多份手机传感器CSV文件?
使用Pandas合并惯性传感器CSV文件(处理时间戳差异与数据间隙)
核心思路
以时间戳为唯一基准,通过外连接对齐所有传感器数据,再针对数据间隙做缺失值填充,同时处理时间戳的细微差异。
具体步骤与代码示例
1. 导入依赖库
import pandas as pd import glob
2. 批量加载传感器CSV文件
通过glob匹配所有目标CSV文件,逐个读取并为列名添加传感器前缀(避免不同传感器的x/y/z列重名),同时确保时间戳列格式统一:
# 匹配所有惯性传感器CSV文件(根据你的实际路径调整) sensor_files = glob.glob("./sensor_data/*.csv") sensor_dfs = {} for file_path in sensor_files: # 提取传感器名称(假设文件名格式为 "Accelerometer.csv" 这类) sensor_name = file_path.split("/")[-1].replace(".csv", "") # 读取CSV,假设时间戳列名为 "timestamp" df = pd.read_csv(file_path) # 将时间戳转为数值型(如果是Unix时间戳)或datetime型 df["timestamp"] = pd.to_numeric(df["timestamp"]) # 为所有数据列添加传感器前缀 df = df.rename(columns={ col: f"{sensor_name.lower()}_{col}" for col in df.columns if col != "timestamp" }) sensor_dfs[sensor_name] = df
3. 对齐时间戳并合并数据
针对两种常见场景处理:
场景1:时间戳完全匹配(仅存在部分文件数据间隙)
将所有DataFrame按时间戳做外连接,保留所有时间戳记录,缺失值留空后再填充:
# 初始化合并后的DataFrame为第一个传感器的数据 merged_df = sensor_dfs[next(iter(sensor_dfs.keys()))] # 循环合并剩余传感器数据 for sensor_name, df in sensor_dfs.items(): if sensor_name == next(iter(sensor_dfs.keys())): continue # 外连接,以timestamp为键 merged_df = pd.merge(merged_df, df, on="timestamp", how="outer") # 按时间戳排序(确保时序正确) merged_df = merged_df.sort_values("timestamp").reset_index(drop=True)
场景2:时间戳存在细微数值差异(如毫秒级误差)
使用merge_asof做近似匹配,按时间戳顺序匹配最近的记录:
# 先将所有DataFrame按时间戳排序 for sensor_name in sensor_dfs: sensor_dfs[sensor_name] = sensor_dfs[sensor_name].sort_values("timestamp") # 初始化合并DataFrame merged_df = sensor_dfs[next(iter(sensor_dfs.keys()))] # 循环做近似合并,设置匹配容忍度(比如50毫秒,根据你的采样频率调整) for sensor_name, df in sensor_dfs.items(): if sensor_name == next(iter(sensor_dfs.keys())): continue merged_df = pd.merge_asof( merged_df, df, on="timestamp", tolerance=50, # 允许的时间戳最大差值(单位与你的时间戳一致) direction="nearest" # 匹配最近的时间戳 )
4. 处理数据间隙(填充缺失值)
传感器数据是连续时序数据,推荐用线性插值填充缺失值,也可根据需求选择前向/后向填充:
# 线性插值填充(适合连续传感器数据) merged_df = merged_df.interpolate(method="linear") # 可选:填充首尾的缺失值(用首尾有效值填充) merged_df = merged_df.fillna(method="ffill").fillna(method="bfill")
5. 保存合并后的文件
merged_df.to_csv("./merged_sensor_data.csv", index=False)
关键注意事项
- 确保所有CSV文件的时间戳单位一致(如都是毫秒级Unix时间)。
- 调整
tolerance参数时,要参考你的传感器采样频率(比如采样频率100Hz,时间间隔10ms,可设tolerance为20ms)。 - 如果时间戳是datetime字符串,先统一转为
pd.to_datetime格式再处理。
内容的提问来源于stack exchange,提问作者Владимир Шеремета
相关产品推荐
相关产品推荐

