【问题标题】:Remove duplicate key value pairs with tolerance by keeping the ones with largest value通过保留具有最大值的键值对来删除具有容差的重复键值对
【发布时间】:2018-12-19 04:20:03
【问题描述】:

我正在尝试使用以下规则从一组键和值中删除具有容差的重复项:

假设以下集合:

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],所以这里是正确的更多的是巧合。

我觉得应该有一个更聪明的方法来做到这一点,但我无法真正理解它。

【问题讨论】:

    标签: arrays matlab duplicates


    【解决方案1】:

    这是我的解决方案:

    Step1. 找出当前keys&vals中的所有非最大值点,在其前面或后面有一个较大的邻居,并建立一个名为Nind的Set。

    Step2. 创建另一个名为 Cind 的 Set,其中包含每个具有近邻且需要在当前键值和值中考虑的点。

    Step3.NindCind相交,删除KeysVals中的相同部分。

    Step4.如果两个集合的交集为空,则转到Step5。在其他情况下,转到 Step1

    Step5.到此结束~

    请注意,while 循环正在处理一些具有多个最大点的丑陋输入,例如:

    我的代码:

    %% 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]
    

    代码的输出是:

    ans =
    
        1.0000    2.0000    3.1000    4.0000    5.0000
        0.8000    1.0000    1.3000    1.0000    1.1000
    

    【讨论】:

    • 嗨,蒋,这很好用!我只是将一行更改为Cind=[0 diff(keys)&lt;0.5 &amp; abs(diff(keys)&gt;0.01)];,因为我还必须摆脱“真正的”重复。感谢您的帮助!
    • 没关系,很高兴能帮上忙~@Axel
    • 嗨,江,当我尝试在不同的设备上使用您的解决方案时遇到了一些问题。我将这些问题放入stackoverflow.com/questions/51288027/… 的新问题中。也许你可以在那里看看。干杯!
    • @Axel 看来我的代码还是有一些问题,过几天我会尽力修复。此外,我在您的新帖子中提供了一个简单的解决方案,希望对您有所帮助。
    猜你喜欢
    • 2012-09-30
    • 2017-12-31
    • 2020-06-14
    • 2012-12-12
    • 1970-01-01
    • 2018-11-06
    • 2011-08-22
    • 1970-01-01
    • 2018-06-27
    相关资源
    最近更新 更多