拿到一串离散的位置点,怎么把速度算出来?这个问题我太熟了。做物理实验、处理传感器数据、分析运动轨迹的时候基本都会遇到——你以为不就是相邻两点距离除以时间嘛,等你真正把代码跑起来,看到那张抖成心电图的速度曲线,就知道这事没那么简单。今天就把我从“直接diff被噪声教做人”到“一套完整可落地的方案”的实战经验整理出来,覆盖离散数据求速度的数学原理、方法选型、Python实现和避坑技巧,适合正在处理实验数据的学生、做信号处理的工程师,以及任何被离散微分困扰的朋友参考。
1. 离散数据里的“速度”,先把定义掰扯清楚
1.1 连续求导和离散差分,差在哪
先说个根本问题:速度的物理定义是位移对时间的变化率,连续情况下就是求导,v(t) = dx/dt。但工程里几乎没有真正的连续函数,拿到手的永远是一个个离散的采样点——传感器每秒采 10 次、100 次,或者实验测得一组位置-时间对。这时候微积分教材里那套求导规则直接失效了,因为我们根本不知道采样点之间物体是怎么运动的。
离散求速度,本质上不是“求导”,而是“估计导数”。我们假设相邻两个采样点之间近似做匀速直线运动,然后用差分去逼近真实的导数。差分是用函数值的差除以自变量的差,它是导数定义里那个极限还没取的样子。
这里有个核心认知必须建立:离散差分算出来的速度,天然带有误差。误差来自泰勒展开中那些被丢掉的更高阶项。举个直观例子,假设真实运动是匀加速直线运动 x = t²,在 t=1 附近用不同差分方式算速度,结果会明显偏离真实值 v(1)=2。这不是代码写错了,是离散化本身的信息损失,任何算法都绕不开。
1.2 三种基础差分:前向、后向、中心差分
搞清楚这个,再看具体怎么算。假设位置序列是 x₀, x₁, x₂, …, xₙ,对应时间戳是 t₀, t₁, t₂, …, tₙ,时间间隔均匀为 Δt。有三种最基础的差分方式:
前向差分:vᵢ = (xᵢ₊₁ - xᵢ) / Δt
后向差分:vᵢ = (xᵢ - xᵢ₋₁) / Δt
中心差分:vᵢ = (xᵢ₊₁ - xᵢ₋₁) / (2Δt)
用泰勒展开能分别算出它们的截断误差。前向和后向差分只保留了泰勒展开到一阶项,误差是 O(Δt),也就是时间间隔越小误差越小,但只按线性缩小。中心差分把前后两项一减,二阶项抵消掉了,误差直接变成 O(Δt²),同样的采样间隔,精度高一个量级。我把它们的特性整理在下面:
| 差分方式 | 公式 | 截断误差 | 优点 | 缺点 |
|---|---|---|---|---|
| 前向差分 | (xᵢ₊₁ - xᵢ) / Δt | O(Δt) | 只用未来点,适合实时计算 | 精度低,有一阶滞后 |
| 后向差分 | (xᵢ - xᵢ₋₁) / Δt | O(Δt) | 只用过去点,适合实时计算 | 精度低,滞后方向不同 |
| 中心差分 | (xᵢ₊₁ - xᵢ₋₁) / (2Δt) | O(Δt²) | 精度高,无系统滞后 | 需要前后各一个点,无法处理边界 |
实操里,如果数据是离线处理的,且位置数据本身比较干净,中心差分是首选。它在频域上的特性也更好——不会像前向差分那样给整个速度信号引入一个偏移或相位畸变。但如果做的是实时系统,比如机器人控制回路里要当前时刻的速度,那就只能用前向或后向差分,因为中心差分需要等下一个采样点到来才能算,天然有延迟。
1.3 时间间隔不均匀怎么办
很多真实场景里,采样时间戳并不是均匀的。嵌入式系统的中断调度有抖动,GPS 数据的输出时刻也经常漂移,甚至数据预处理时还会丢包。这时候如果直接按下标当等间隔处理,算出来的速度会带进一层额外误差。
正确做法是:差分时必须用真实时间戳。中心差分的通用形
