我正在尝试从一组键值对中删除重复数据。这些重复具有完全相同的键,或者键可以彼此非常接近。在那种情况下,我只想保留最大的键值对。
中提供的解决方案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 & abs(diff(keys)>0.01)];
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
适用于给定的一对配对
keys = [1 2 3 3.1 3.15 4 5];
vals = [0.8 1 1.1 1.3 1.2 1 1.1];
所以当输入看起来像
然后输出看起来像这样
删除3
和6
周围的重复。
但是,如果我对集合应用相同的解决方案
keys = [414 414 999 1011 1070 1280 1280 1635 1641 1793 1799 1870 1872 1886 2213 2214 2225 2572 3778 3790 4970];
values = [1.100 1.100 0.316 0.198 0.224 0.555 0.555 0.443 0.374 0.387 0.510 0.446 0.456 0.347 0.224 0.229 0.171 0.175 0.202 0.183 0.147];
并相应地将阈值更改为
Cind=[0 diff(keys)<13 & abs(diff(keys)>0.01)];
然后输入看起来像
输出看起来像
在这种情况下,问题是删除了太多点。例如,在红色圆圈中,该组中的最大点被删除,并且该区域中的三个点中,尽管距离远高于设置的阈值13,但仅保留了一个点。尽管所有较大的值都被删除,但在1635中的点也被删除了再走13点。
我在这里误会什么?
编辑:期望的输出将是那些键值对非常接近的那些键值对,只有一对最大的键将被保留,而另一个键将被从两者中删除。数组。我指出了应该合并到该图中最大值的那些点:
编辑2:因此,所需的输出数组将是:
keys = [414 999 1070 1280 1635 1799 1872 1886 2213 2225 2572 3778 4970];
vals = [1.100 0.316 0.224 0.555 0.443 0.510 0.456 0.347 0.224 0.171 0.175 0.202 0.147];
答案 0 :(得分:1)
似乎该代码将删除两个相邻的点,其中一个接近一个较大的值,第二个点与第一个被删除的点接近,但不会保留较大的值。最简单的解决方法(不是最漂亮的解决方法)是在循环的每次迭代中仅删除一个元素。例如:
while true % changed code
%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)<13 & abs(diff(keys)>0.01)];
Cind(find(Cind)-1)=1;
vec=1:length(Cind);
Cind=Cind.*vec;
Cind(Cind == 0)=[];
%check through & back
ind=intersect(Cind,Nind);
if isempty(ind) % added code
break % added code
end % added code
ind=ind(1); % added code
keys(ind)=[];
vals(ind)=[];
end
PS:为什么将& abs(diff(keys)>0.01)
添加到上一个答案?它会导致保留非常接近的要点,这与您对问题的描述不同,这不是您的意图。
答案 1 :(得分:1)
这是一种直接,非常简单的策略,它仅包含一些if语句并一次删除一个点,但是仍然有效。
但是,以下代码的复杂度为 O(N ^ 2),与向量化无关,当输入变得可观时,这将非常耗时。
%% Input
clc; clear;
keys = [414 414 999 1011 1070 1280 1280 1635 1641 1793 1799 1870 1872 1886 2213 2214 2225 2572 3778 3790 4970];
vals = [1.100 1.100 0.316 0.198 0.224 0.555 0.555 0.443 0.374 0.387 0.510 0.446 0.456 0.347 0.224 0.229 0.171 0.175 0.202 0.183 0.147];
%% Dealing
[len,flag]=deal(13,1);
while flag
flag=0;
for ii=2:length(keys)
if ((keys(ii)-keys(ii-1) > len))
continue;
else
if (vals(ii) > vals(ii-1))
keys(ii-1)=[];
vals(ii-1)=[];
else
keys(ii)=[];
vals(ii)=[];
end
flag=1;
break;
end
end
end
%% plot
figure(1)
plot(keys,vals)
hold on
plot(keys,vals,'ro')
for ii=1:length(vals)
text(keys(ii),vals(ii),num2str(ii))
end
代码将输出: