Matlab 从XY数据的多个时间序列中提取平均轨迹
我有11719个XY坐标对,它们来自6个不同的跟踪洋流的仪器(它们测量UTC时间、经度、纬度和温度)。这些仪器漂移,因此在同一位置没有重复测量。我需要从XY数据中提取“平均轨迹”。以下是数据集: 我在想一条回归线,但我想要得到的平均轨迹显然不是线性的。我尝试过使用不同的拟合函数,例如通过cftool(lon,lat)平滑样条曲线,但这不是最方便的方法,因为我需要将数据分割成子集,然后以某种方式合并不同的函数。您可以使用它来绘制数据并以交互方式使用不同的模型。请注意,Matlab 从XY数据的多个时间序列中提取平均轨迹,matlab,regression,mean,spline,Matlab,Regression,Mean,Spline,我有11719个XY坐标对,它们来自6个不同的跟踪洋流的仪器(它们测量UTC时间、经度、纬度和温度)。这些仪器漂移,因此在同一位置没有重复测量。我需要从XY数据中提取“平均轨迹”。以下是数据集: 我在想一条回归线,但我想要得到的平均轨迹显然不是线性的。我尝试过使用不同的拟合函数,例如通过cftool(lon,lat)平滑样条曲线,但这不是最方便的方法,因为我需要将数据分割成子集,然后以某种方式合并不同的函数。您可以使用它来绘制数据并以交互方式使用不同的模型。请注意,cftool使用叠加回归线绘制
cftool
使用叠加回归线绘制数据。有11719个点。可以像这样检测连续段
d = load('summerRunningMean.csv');
% detect continuous parts
s = sqrt(sum(diff(d)' .^ 2));
ind = [0, find(s > 100 * mean(s)), size(d, 1)];
这导致6段长度从534点到4255点
绘制空间中叠加的轨迹
for i = 1 : 6
x = d(ind(i) + 1 : ind(i + 1), 1);
y = d(ind(i) + 1 : ind(i + 1), 2);
plot(x, y)
hold all
end
xlabel x
ylabel y
axis equal
给出了这个结果
显示轨迹的形状大致相同,除了一个轨迹外,所有轨迹都从同一个位置开始
然而,时间序列的叠加显示,沿着该形状的运动以不同的速度发生:
因此,对这些数据进行统计的问题是,没有共同的参考点来将来自不同轨迹的数据点分配给彼此
在下文中,我排除了第6轨道,因为它的起点与其他轨道不同
定义此类公共参考的一种方法是计算沿轨道的曲线长度:
l = [0 ; cumsum(sqrt(diff(x) .^ 2 + diff(y) .^ 2))];
在该长度上而不是在一段时间内进行绘图会使x和y坐标更加相似,因此具有可比性:
根据这个结果,可以计算平均值和其他统计数据。要真正做到这一点,数据必须通过插值重新参数化:
li = 0 :0.001: l(end);
xi = interp1(l, x, li);
yi = interp1(l, y, li);
现在,对于每个轨迹,我们都有一个公共参考,可以将转换后的数据存储在公共数据矩阵中:
n = numel(li);
xp(1 : n, i) = xi;
yp(1 : n, i) = yi;
其中i
是轨迹索引。矩阵xp
和yp
必须初始化为NaNs,因为轨迹的长度不同。然后,可以计算统计数据,例如,平均值:
xm = nanmean(xp, 2);
ym = nanmean(yp, 2);
生成的平均轨迹与原始轨迹一起:
为了进一步改善轨道之间的一致性,可以对轨道进行平滑处理,以减少随机变化(
span=5000
似乎效果良好):
之后,必须重新计算曲线长度参数:
l = [0 ; cumsum(sqrt(diff(xs) .^ 2 + diff(ys) .^ 2))];
结果是:
作为共同参考的基础的协议显然得到了改进。数据必须再次重新参数化
li = 0 :0.001: l(end);
xsi = interp1(l, xs, li);
ysi = interp1(l, ys, li);
结果存储在公共数据矩阵中
n = numel(li);
xp(1 : n, i) = xsi;
yp(1 : n, i) = ysi;
然后计算平均值
xm = nanmean(xp, 2);
ym = nanmean(yp, 2);
生成的平均轨迹与原始轨迹一起:
结果看起来平滑多了。但是,平滑减少了两条轨迹末端大回路的周长,因此“平均轨迹”不再位于原始轨迹之间。可通过span
的值调节平滑度和接近原始轨道之间的平衡
此处包含生成最后一个图形的完整代码;为了再现非平滑版本,设置
span=1代码>
d = load('summerRunningMean.csv');
% detect tracks as continuous segments
s = sqrt(sum(diff(d)' .^ 2));
ind = [0, find(s > 100 * mean(s)), size(d, 1)];
% remove 6th track because itis an outlier
ind = ind(1 : end - 1);
N = size(ind, 2) - 1;
% smoothing parameter
span = 5000;
xp = nan(13000, N); % I know, hardcoded, not nice.
yp = nan(13000, N);
for i = 1 : N
% extract data
x = d(ind(i) + 1 : ind(i + 1), 1);
y = d(ind(i) + 1 : ind(i + 1), 2);
% determine length along curve
% to use as curve parameter
l = [0 ; cumsum(sqrt(diff(x) .^ 2 + diff(y) .^ 2))];
% reparametrize by interpolation
li = 0 :0.001: l(end);
xi = interp1(l, x, li);
yi = interp1(l, y, li);
% smooth to remove small deviations
xs = smooth(xi, span);
ys = smooth(yi, span);
% determine length along smoothed curve
% as improved curve parameter
l = [0 ; cumsum(sqrt(diff(xs) .^ 2 + diff(ys) .^ 2))];
% again, reparametrize by interpolation
li = 0 :0.001: l(end);
xsi = interp1(l, xs, li);
ysi = interp1(l, ys, li);
% store
n = numel(li);
xp(1 : n, i) = xsi;
yp(1 : n, i) = ysi;
plot(x, y)
axis equal
hold all
end
% compute mean
xm = nanmean(xp, 2);
ym = nanmean(yp, 2);
% plot mean
plot(xm, ym, 'k', 'LineWidth', 2)
xlabel x
ylabel y
所以你有5个不同的xy坐标时间序列,对吗?如果您没有“轨迹”的模型,最简单的方法是首先同时对5个时间序列进行平均(如果定义了这一点),然后对固定时间范围的滑动窗口进行平均。如果你有你的数据图,把它贴在这里,这样我们可以得到一个想法。谢谢你的快速回复。我尝试了最简单的方法,但问题是这5条轨迹是在不同的时间(间隔1到2周)测量的,每条轨迹的长度(空间和时间)也不同。我已经在Matlab中使用散射绘制了所有数据(我将尝试发布),并使用平滑器查看。我还将尝试将数据发布到数据集,以便您可以看到。再次感谢你的帮助!不客气。你也可以,如果可以的话,发布数据。。。没有明显的方法将文档附加到线程。。
d = load('summerRunningMean.csv');
% detect tracks as continuous segments
s = sqrt(sum(diff(d)' .^ 2));
ind = [0, find(s > 100 * mean(s)), size(d, 1)];
% remove 6th track because itis an outlier
ind = ind(1 : end - 1);
N = size(ind, 2) - 1;
% smoothing parameter
span = 5000;
xp = nan(13000, N); % I know, hardcoded, not nice.
yp = nan(13000, N);
for i = 1 : N
% extract data
x = d(ind(i) + 1 : ind(i + 1), 1);
y = d(ind(i) + 1 : ind(i + 1), 2);
% determine length along curve
% to use as curve parameter
l = [0 ; cumsum(sqrt(diff(x) .^ 2 + diff(y) .^ 2))];
% reparametrize by interpolation
li = 0 :0.001: l(end);
xi = interp1(l, x, li);
yi = interp1(l, y, li);
% smooth to remove small deviations
xs = smooth(xi, span);
ys = smooth(yi, span);
% determine length along smoothed curve
% as improved curve parameter
l = [0 ; cumsum(sqrt(diff(xs) .^ 2 + diff(ys) .^ 2))];
% again, reparametrize by interpolation
li = 0 :0.001: l(end);
xsi = interp1(l, xs, li);
ysi = interp1(l, ys, li);
% store
n = numel(li);
xp(1 : n, i) = xsi;
yp(1 : n, i) = ysi;
plot(x, y)
axis equal
hold all
end
% compute mean
xm = nanmean(xp, 2);
ym = nanmean(yp, 2);
% plot mean
plot(xm, ym, 'k', 'LineWidth', 2)
xlabel x
ylabel y