从几个时间序列的XY数据中提取平均轨迹

时间:2013-10-30 16:35:16

标签: matlab regression mean spline

我有11,719个XY坐标对,它们来自6个跟踪洋流的不同仪器(它们测量UTC时间,经度,纬度,温度)。这些仪器漂移,因此在同一地点没有重复措施。我需要提取一个平均曲目"从那个XY数据。这是数据集:http://dropbox.com/s/dg0psl3hnmilg44/summerdrifters.csv

我在考虑一条回归线,但我想得到的平均轨迹显然不是线性的。我尝试使用不同的拟合函数,例如通过cftool(lon,lat)平滑样条曲线,但这不是最方便的方法,因为我需要将数据分成子集,然后以某种方式合并不同的函数。

2 个答案:

答案 0 :(得分:2)

data set有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

给出了这个结果

tracks in space

并显示曲目的形状大致相同,除了其中一个曲目外,所有曲目都从同一个地方开始。

然而,时间序列的叠加表明沿着该形状的运动以不同的速度发生:

superimposed time series

对此数据进行统计的问题是,没有共同的参考点可以将不同轨道的数据点相互分配。

在下文中,我排除了#6轨道,因为它的起点与其他轨道不同。


定义这种公共参考的一种方法是沿轨道计算曲线长度

l = [0 ; cumsum(sqrt(diff(x) .^ 2 + diff(y) .^ 2))];

在此长度上绘制而不是随着时间的推移使得x和y坐标更相似,因此具有可比性:

coordinates over curve length

从这个结果中,可以计算平均值和其他统计量。要实际执行此操作,必须通过插值重新参数化数据:

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是轨道索引。必须将矩阵xpyp初始化为NaN,因为轨道具有不同的长度。然后,可以计算统计数据,例如,平均值:

xm = nanmean(xp, 2);
ym = nanmean(yp, 2);

由此产生的平均曲目和原始曲目:

added mean track


为了进一步改善曲目之间的协议,可以平滑它们以减少随机变化(span = 5000似乎运作良好):

xs = smooth(xi, span);
ys = smooth(yi, span);

之后,必须重新计算曲线长度参数:

l = [0 ; cumsum(sqrt(diff(xs) .^ 2 + diff(ys) .^ 2))];

结果:

smoothed coordinates over curve length

共同参考的基础协议已明显改善。数据再次被重新参数化

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);

由此产生的平均曲目和原始曲目:

added smoothed mean track

结果看起来更顺畅。然而,平滑减小了两个轨道末端的大环的周长,因此“平均轨道”不再位于原始轨道之间。可以通过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

答案 1 :(得分:0)

您可以使用scatter(X,Y)绘制数据,cftool(X,Y)可以使用不同的模型进行交互式播放。请注意,cftool使用叠加回归线绘制数据。