我需要将第一列中的值近似到第二列中最接近的值(我知道需要一个阈值,它可能是0.0090)并保存索引。 我使用以下内容:
[ms, ix] = sort(m(:));
[r, c] = ind2sub(size(m),ix);
proximity_threshold = 0.0090;
ind = (diff(ms)<proximity_threshold);
ind(end+1)=0;
n=0;
nn=0;
while n<numel(ix)
n=n+1;
nn=nn+1;
if ind(n) & c(n)~=c(n+1)
a(nn,c(n))=ms(n);
a(nn,c(n+1))=ms(n+1);
n=n+1;
else
a(nn,c(n))=ms(n);
end
end
但我对此实施不满意。它近似值,但它返回一个大小(900 x 2)的矩阵,我想要一个与原始矩阵相同的矩阵(500x2)。
谢谢!
答案 0 :(得分:3)
首先,您可以跳过矩阵m
。在这种情况下,这是一个不太理想的解决问题的方法。另外,摆脱x_t
末尾的零点。它们不是必需的。如果您需要帮助修剪零结束,请尝试:
x_t = x_t(1:find(x_t~=0,1,'last'));
现在,为了匹配。您可以使用以下内容在x_t
中找到与x
元素最接近的匹配项:
B = bsxfun(@minus, x_t(:), x(:).'); %'
[idx,~] = find(bsxfun(@eq, abs(B), min(abs(B))));
y = x_t(idx);
现在x
中可以找到y
的近似值,并在idx
中找到相应的索引。
bsxfun(@minus, x, y);
这将采用列向量x
并通过行向量y
的每个元素或每个元素减去它。例如,
>> x = [3 6 9 12].'; y = [1 2 3];
>> ans = bsxfun(@minus, x, y);
ans =
2 1 0
5 4 3
8 7 6
11 10 9
或换句话说,正在发生的事情是:
ans =
(3-1) (3-2) (3-3)
(6-1) (6-2) (6-3)
(9-1) (9-2) (9-3)
(12-1) (12-2) (12-3)
bsxfun(@eq, A, min(A));
这将在列最小值所在的矩阵A
的列中查找位置。它返回一个逻辑矩阵(1和0)。例如,
>> A = [ 1 2 3 4;
3 3 6 5;
2 2 0 7;
5 1 8 5;
4 5 2 6];
>> ans = bsxfun(@eq, A, min(A))
ans =
1 0 0 1
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 0
[idx,~] = find(A);
find
命令搜索矩阵A
的所有非零元素。通常你会把它称为[row, col] = find(A);
来取回行和列,但由于我只对行感兴趣,我使用~
告诉Matlab我不想保留列值
y = x(idx);
这会创建一个新的向量y
,其中包含x
引用的idx
元素。由于我已经找到了最小化错误的索引,因此我使用它们来获取这些索引处的x
值。
全部放在一起:
在较高级别,代码执行以下操作:
B
将x
(列)的每个值与x_t
(行)的每个值进行比较
x
的每一列(B
),找到最小化错误的行(x_t
)。
x_t
值。
希望这有帮助!
我意识到,如果x
的值与x_t
的两个值之间的距离完全相同,那么您最终会得到一个太长的向量,因为会选择多个答案。以下是问题的解决方法。
B = bsxfun(@minus, x_t(:), x(:).'); %'
[idx,col] = find(bsxfun(@eq, abs(B), min(abs(B))));
idx(1 < sum(triu(bsxfun(@eq, col(:), col(:).')))) = []; %'
y = x_t(idx);
基本上,添加的行会丢弃与给定列中第一个匹配项不对应的任何索引值。
答案 1 :(得分:2)
nispio的答案很好,但匹配比必要复杂得多。 interp1
函数可用于将值映射到查找表条目。
根据nispio的方法修剪x_t:
x_t = x_t(1:find(x_t~=0,1,'last'));
现在我们使用专为表查找设计的功能。
idx = interp1(x, 1:numel(x), x_t, 'nearest');
最后,获取找到的值,与nispio相同:
y = x(idx);