如何对DataFrame时间序列重采样,统一各序列行数至指定数量?
时间序列统一行数的重采样方案
核心思路
针对运动轨迹数据的连续特性,先补全高精度时间轴,再通过插值实现统一行数,尽可能保留轨迹的细节特征,减少信息损失。
具体步骤
生成连续高精度时间戳
原始timestamp仅到秒级,同一秒内的观测无细分时间标记,需为每行分配连续时间:- 按标签分组处理每个独立轨迹序列,对每组内相同
timestamp的行,分配秒内递增索引 - 计算每秒内的总行数,将每行时间戳转为
t + 秒内索引/每秒行数,让同一秒内的时间均匀分布在[t, t+1)区间,得到连续的时间轴
- 按标签分组处理每个独立轨迹序列,对每组内相同
计算目标采样点
对每个序列:- 计算连续时间轴的总跨度(最大时间 - 最小时间)
- 用
np.linspace生成15000个均匀分布的目标时间点,覆盖整个序列的时间范围
插值实现重采样
- 下采样(原行数>15000):用目标时间点对原序列做三次样条插值(或线性插值,依运动特性选择),平滑提取15000个点,比直接取点更能保留轨迹的连续趋势和细节
- 上采样(原行数<15000):同样用目标时间点插值,优先选三次样条插值保证轨迹平滑;字符串标签属于整个序列的标识,直接填充统一值即可
代码示例(Pandas实现)
import pandas as pd import numpy as np # 假设df包含timestamp, acc_x, acc_y, acc_z, rot_x, rot_y, rot_z, label列 target_rows = 15000 resampled_dfs = [] # 按标签分组处理每个独立轨迹 for label, group in df.groupby('label'): # 重置索引确保顺序正确 group = group.reset_index(drop=True) # 生成秒内索引和每秒行数 group['second_idx'] = group.groupby('timestamp').cumcount() group['second_count'] = group.groupby('timestamp')['timestamp'].transform('count') # 构造连续时间轴(单位:秒) group['continuous_time'] = group['timestamp'] + group['second_idx'] / group['second_count'] # 生成目标采样时间点 min_t, max_t = group['continuous_time'].min(), group['continuous_time'].max() target_times = np.linspace(min_t, max_t, target_rows) # 重置索引为连续时间,插值采样 group = group.set_index('continuous_time').drop(['timestamp', 'second_idx', 'second_count'], axis=1) resampled_group = group.reindex(target_times) # 数值列用三次样条插值,标签列填充统一值 numeric_cols = ['acc_x', 'acc_y', 'acc_z', 'rot_x', 'rot_y', 'rot_z'] resampled_group[numeric_cols] = resampled_group[numeric_cols].interpolate(method='cubic') resampled_group['label'] = label resampled_dfs.append(resampled_group) # 合并所有重采样后的序列 final_df = pd.concat(resampled_dfs).reset_index().rename(columns={'index': 'continuous_time'})
注意事项
- 若原始序列未按时间排序,需先对每个分组按
timestamp和second_idx排序 - 若运动轨迹存在突变(如突然转向),可将插值方法改为
linear,避免样条插值引入过度平滑的虚假特征 - 可抽取少量序列对比原数据和重采样数据的关键特征(如加速度峰值、旋转角度变化),验证信息损失程度
内容的提问来源于stack exchange,提问作者Unistack
相关产品推荐
相关产品推荐

