在python中使用容差来统一数组/列表(uniquetol等效)

时间:2016-06-15 22:44:41

标签: python numpy unique

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

例如,对于数组/列表

[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有特权)

2 个答案:

答案 0 :(得分:4)

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.1的容差在0.3的容差范围内。然后,1.1 1.32.02.1In [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])

请注意,这将创建一个独特的阵列,其中包含&#34; chained-closeness&#34;校验。举个例子:

1.3

因此,1.1由于1.5而消失1.3,{{1}}由于{{1}}而消失。

答案 1 :(得分:1)

在纯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]

...这与你的例子一致。