Python fastdtw包使用:如何将长时序信号规整为短参考时序的对应长度
问题原因
fastdtw(A,B)返回的对齐路径path长度默认近似等于两个输入序列中更长的那个的长度。你第二个场景中将短序列y作为参考放在第一个参数、长序列x放在第二个参数时,路径长度还是近似x的长度1000,直接取所有路径点对应的x索引自然得到长度为1000的结果,不符合预期。
要将长序列规整到短参考序列的长度,只需按参考序列的索引对匹配的长序列点做聚合即可:每个参考序列位置对应的所有长序列匹配点,计算一个聚合值(常用均值、中位数,也可根据业务需求取首尾匹配点),最终结果长度就和参考序列一致。
实现代码
方法1:均值聚合(精度更高,推荐)
from scipy.spatial.distance import euclidean from fastdtw import fastdtw import numpy as np # 生成测试信号 x = np.cos(2*np.pi*np.power(3*(np.linspace(1, 1000, 1000))/1000, 2)) y = np.cos(2*np.pi*(9*(np.linspace(1, 399, 399))/400)) # 计算DTW路径,参考序列y放第一个参数 distance, path = fastdtw(y, x, dist=euclidean) # 按y的索引分组聚合x的匹配值 x_warped = [] current_y_idx = -1 temp_x_buffer = [] for y_idx, x_idx in path: if y_idx != current_y_idx: if current_y_idx != -1: # 可根据需求替换为np.median、temp_x_buffer[0](取第一个匹配点)、temp_x_buffer[-1](取最后一个匹配点) x_warped.append(np.mean(temp_x_buffer)) current_y_idx = y_idx temp_x_buffer = [] temp_x_buffer.append(x[x_idx]) # 处理最后一组数据 x_warped.append(np.mean(temp_x_buffer)) x_warped = np.array(x_warped) # 验证维度 print(x_warped.shape) # 输出为 (399,)
方法2:去重取最后匹配点(速度更快,适合低精度场景)
# 对路径按y索引去重,保留每个y位置最后匹配的x索引 y_to_x_map = {} for y_idx, x_idx in path: y_to_x_map[y_idx] = x_idx x_warped = x[list(y_to_x_map.values())] print(x_warped.shape) # 输出为 (399,)
通用对齐逻辑总结
不管参考序列长短,要将待规整序列对齐到参考序列长度,统一遵循以下逻辑:
- 参考序列传入
fastdtw的第一个参数,待规整序列传入第二个参数 - 若参考序列更长:直接取所有路径点对应的待规整序列索引(即你第一个场景的写法,短序列点会被重复,长度自动匹配长参考)
- 若参考序列更短:按参考序列的索引分组聚合待规整序列的匹配点,得到和参考长度一致的结果
内容的提问来源于stack exchange,提问作者Mohammad
相关产品推荐
相关产品推荐

