【问题标题】:uniquify an array/list with a tolerance in python (uniquetol equivalent)在 python 中使一个具有容差的数组/列表唯一化(uniquetol 等效项)
【发布时间】:2016-06-15 22:44:41
【问题描述】:

我想在某个容差范围内找到数组的唯一元素

例如,对于一个数组/列表

[1.1 , 1.3 , 1.9 , 2.0 , 2.5 , 2.9]

函数将返回

[1.1 , 1.9 , 2.5 , 2.9]

如果容差是0.3

有点像 MATLAB 函数 http://mathworks.com/help/matlab/ref/uniquetol.html (但此函数使用相对容差,绝对容差就足够了) 实现它的pythonic方式是什么? (numpy 有特权)

【问题讨论】:

  • 如果输入是[ 1.1, 1.3, 1.5, 2. , 2.1, 2.5, 2.9],那么对于0.3 的容差,输出必须是什么?
  • 另外,输入是否总是排序的?

标签: python numpy unique


【解决方案1】:

A 作为输入数组,tol 作为容差值,我们可以采用NumPy broadcasting 的矢量化方法,就像这样 -

A[~(np.triu(np.abs(A[:,None] - A) <= tol,1)).any(0)]

示例运行 -

In [20]: A = np.array([2.1,  1.3 , 1.9 , 1.1 , 2.0 , 2.5 , 2.9])

In [21]: tol = 0.3

In [22]: A[~(np.triu(np.abs(A[:,None] - A) <= tol,1)).any(0)]
Out[22]: array([ 2.1,  1.3,  2.5,  2.9])

注意 1.9 已消失,因为我们的 2.10.3 的容差范围内。然后,1.11.32.0 取代 2.1

请注意,这将创建一个具有“链式接近性”检查的唯一数组。举个例子:

In [91]: A = np.array([ 1.1,  1.3,  1.5,  2. ,  2.1,  2.2, 2.35, 2.5,  2.9])

In [92]: A[~(np.triu(np.abs(A[:,None] - A) <= tol,1)).any(0)]
Out[92]: array([ 1.1,  2. ,  2.9])

因此,1.31.1 而消失,1.51.3 而消失。

【讨论】:

    【解决方案2】:

    在纯 Python 2 中,我编写了以下代码:

    a = [1.1, 1.3, 1.9, 2.0, 2.5, 2.9]                                              
    
    # Per http://fr.mathworks.com/help/matlab/ref/uniquetol.html                                                                                    
    tol = max(map(lambda x: abs(x), a)) * 0.3                                       
    
    a.sort()                                                                        
    
    results = [a.pop(0), ]                                                          
    
    for i in a:
        # Skip items within tolerance.                                                                     
        if abs(results[-1] - i) <= tol:                                             
            continue                                                                
        results.append(i)                                                           
    
    print a                                                                         
    print results
    

    结果

    [1.3, 1.9, 2.0, 2.5, 2.9]
    [1.1, 2.0, 2.9]
    

    规范似乎同意,但与您的示例不一致。

    如果我只是将容差设置为0.3 而不是max(map(lambda x: abs(x), a)) * 0.3,我会得到:

    [1.3, 1.9, 2.0, 2.5, 2.9]
    [1.1, 1.9, 2.5, 2.9]
    

    ...这与您的示例一致。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 1970-01-01
      相关资源
      最近更新 更多