Matlab 按最近时间对齐数据阵列

Matlab 按最近时间对齐数据阵列,matlab,indexing,time-series,sampling,closest,Matlab,Indexing,Time Series,Sampling,Closest,我有2个数据向量和相应的时间向量。此数据几乎同时采样,但时间戳略有不同(来自机器精度传输延迟等)。由于遥测问题,一个或两个数据向量偶尔会出现数据丢失和双采样 我想将数据数组与其时间匹配的位置进行匹配,以便在它们之间执行一些数学运算。基本上从y1和y2中删除没有相应时间x1和x2的点(大约在采样率的1/2范围内视为匹配) 注意:我不想插入y1&y2 %Sample time stamps: Real ones are much faster and not as neat. x1 = [1 2

我有2个数据向量和相应的时间向量。此数据几乎同时采样,但时间戳略有不同(来自机器精度传输延迟等)。由于遥测问题,一个或两个数据向量偶尔会出现数据丢失和双采样

我想将数据数组与其时间匹配的位置进行匹配,以便在它们之间执行一些数学运算。基本上从
y1
y2
中删除没有相应时间
x1
x2
的点(大约在采样率的1/2范围内视为匹配)

注意:我不想插入
y1
&
y2

%Sample time stamps: Real ones are much faster and not as neat.
x1 = [1  2 3 4 5 5.1 6   7   8       10  ]; %note double sample at ~5.
x2 = [.9       4.9    5.9 6.9 8.1 9.1 10.1]; %Slightly different times.

%Sample data:  y is basically y1+1 if no data was missing
y1 = [1 2 3 4 5 5 6 7 8    10];
y2 = [2       6   7 8 9 10 11];

因此,结果应该如下所示:

y1_m = [1 5 6 7 8 10];
y2_m = [2 6 7 8 9 11];
到目前为止我掌握的内容:我使用
interp1
查找两个时间数组之间最近的时间点。然后得到它们之间的时间差,如下所示:

>> idx = interp1(x2,1:numel(x2),x1,'nearest','extrap')
idx =
     1     1     2     2     2     2     3     4     5     7

>> xDelta = abs(x2(idx) - x1)
xDelta =
    0.1000    1.1000    1.9000    0.9000    0.1000    0.2000    0.1000    0.1000    0.1000    0.1000

现在我想我需要做的是为每个唯一的
idx
找到min
xDelta
,这应该会得到所有匹配点。然而,我还没有想出一个聪明的方法来做到这一点。。。似乎accumarray在这里应该很有用,但到目前为止,我没有使用它。

这里有一个粗略的想法,您可能会在使用和:


另请参见:。

这是一个基于@Cris Luengo对原始问题的评论的解决方案

它使用
sortrows
unique
来获得每个数据点配对的最低时间误差

%Sample time stamps: Real ones are much faster and not as neat.
x1 = [1  2 3 4 5 5.1 6   7   8       10  ]; %note double sample at ~5.
x2 = [.9       4.9    5.9 6.9 8.1 9.1 10.1]; %Slightly different times.

%Sample data:  y is basically y1+1 if no data was missing
y1 = [1 2 3 4 5 5 6 7 8    10];
y2 = [2       6   7 8 9 10 11];

%Find the nearest match
idx   = interp1(x2,1:numel(x2),x1,'nearest','extrap');
xDiff = abs(x2(idx) - x1);

% Combine the matched indices & the deltas together & sort by rows.
%So lowest delta for a given index is first.
[A, idx1]    = sortrows([idx(:) xDiff(:)]);
[idx2, uidx] = unique(A(:,1),'first');
idx1         = idx1(uidx); %resort idx1

%output
y1_m = y1(idx1)
y2_m = y2(idx2)


y1_m =
     1     5     6     7     8    10
y2_m =
     2     6     7     8     9    11

有趣的问题!请先以循环的形式写这篇文章,它可能足够快,而且可读性更好。矢量化的解决方案可能涉及使用索引和增量创建单个数组,并按行对其进行排序(因此首先按索引排序,对于相等的索引,则按增量排序)。接下来,为每个索引选择第一个元素,并在未排序的数组中找到相应的位置。我认为排序索引列上的
unique
会选择每个索引中的第一个?@CrisLuengo我开始循环,索引索引和find语句的索引开始变得复杂。。。很难看。无论如何,根据你的评论,我得到了一个有效的矢量化解决方案。如果你写你的评论作为一个答案,我会接受它,否则我会提交我的,所以这不会没有答案。谢谢。你写这个答案会更容易些。我不认为我上面的草图是一个完整的答案,我必须努力写一个答案,而你已经做了努力…这是一个有趣的方法。我不知道函数
ismembertol
。可能是因为我的公司最近刚从2014b升级到2015a。然而,似乎有些不正确的地方。因为答案不正确
y1_m
应该是
[1 5 6 7 8 10]
@CrisLuengo根据您的评论,这里有一个解决方案。
ans =

     1     5     6     7     8     9
%Sample time stamps: Real ones are much faster and not as neat.
x1 = [1  2 3 4 5 5.1 6   7   8       10  ]; %note double sample at ~5.
x2 = [.9       4.9    5.9 6.9 8.1 9.1 10.1]; %Slightly different times.

%Sample data:  y is basically y1+1 if no data was missing
y1 = [1 2 3 4 5 5 6 7 8    10];
y2 = [2       6   7 8 9 10 11];

%Find the nearest match
idx   = interp1(x2,1:numel(x2),x1,'nearest','extrap');
xDiff = abs(x2(idx) - x1);

% Combine the matched indices & the deltas together & sort by rows.
%So lowest delta for a given index is first.
[A, idx1]    = sortrows([idx(:) xDiff(:)]);
[idx2, uidx] = unique(A(:,1),'first');
idx1         = idx1(uidx); %resort idx1

%output
y1_m = y1(idx1)
y2_m = y2(idx2)


y1_m =
     1     5     6     7     8    10
y2_m =
     2     6     7     8     9    11