我正在尝试使用以下规则从一组键和值中删除容忍的重复项:
假设以下设置:
keys = [1 2 3 3.1 3.15 4 5];
vals = [0.8 1 1.1 1.3 1.2 1 1.1];
现在,我想删除键对非常靠近的那些对,如图中红色圆圈所示。我要保留的键值对是具有最大值的键对(在示例中为中间的[3.1; 1.3]
),因此结果集将为:
keys = [1 2 3.1 4 5];
vals = [0.8 1 1.3 1 1.1];
我尝试使用Matlab的diff
函数来做到这一点
vals_new = keys(~(diff(keys) < 0.5));
keys_new = vals(~(diff(keys) < 0.5));
[M,I] = max(vals(diff(keys) < 0.5));
这为vals_new和keys_new提供了一个新集合,该集合仅包括最后一个重复对,但也缺少最后一个值:
keys_new = [1 2 3.15 4]
vals_new = [0.8 1 1.2 1]
最后一行返回重复对I=2
的最大值的索引,但是不幸的是,它不包括三个重复对[3.15; 1.2]
中的最后一个,因此这是一个巧合,因为此处正确
我觉得应该有一种更聪明的方法来做到这一点,但是我无法真正做到这一点。
答案 0 :(得分:1)
这是我的解决方法:
第1步。。找到当前键和值中所有非最大点,在其前面或后面有一个较大的邻居,并建立一个名为show
的Set。 / p>
第二步。创建另一个名为Nind
的集合,其中包含每个具有近邻且需要在当前键和值中考虑的点。
第3步。与Cind
和Nind
相交,并删除Cind
和Keys
中的相同部分。
第4步。。如果两组的相交为空,请转到第5步。在其他情况下,请转到第1步。
第5步。这是结束〜
请注意,while循环正在处理具有多个最大点的丑陋输入,例如:
我的代码:
Vals
代码的输出是:
%% Input
clc; clear;
keys = [1 2 3 3.1 3.15 4 5];
vals = [0.8 1 1.1 1.3 1.2 1 1.1];
%% Dealing
ind=-1;
while(~isempty(ind))
%find the non-max point
Max=([diff(vals) 0]<0 & [0 -diff(vals)]<0);
Nind=1:length(vals);
Nind(Max)=[];
%determine the range of points
Cind=[0 diff(keys)<0.5];
Cind(find(Cind)-1)=1;
vec=1:length(Cind);
Cind=Cind.*vec;
Cind(Cind == 0)=[];
%check through & back
ind=intersect(Cind,Nind);
keys(ind)=[];
vals(ind)=[];
end
%% Output
[keys;vals]