我想在一定的容差范围内找到数组的唯一元素
例如,对于数组/列表
[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
有特权)
答案 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.3
为2.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])
。
请注意,这将创建一个独特的阵列,其中包含&#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]
...这与你的例子一致。