提问人:Frank Tap 提问时间:11/10/2023 最后编辑:Frank Tap 更新时间:11/10/2023 访问量:82
在列表中查找几乎相等值的列表
Find lists of almost equal values in list
问:
我有一个一维 numpy 数组,我想找到包含几乎相等值的子列表/子数组。这意味着它们之间的差异不超过容忍度。我的意思是,解决方案中有一个中心点,所有其他点的区别不仅限于公差。例如,如果我有和容忍度,期望的结果是 .我认为以下函数可以完成这项工作:[1.0, 2.2, 1.4, 1.8, 1.5, 2.1]
0.2
[[1.4, 1.5], [2.1, 2.2]]
import numpy as np
def find_almost_equal(input, tol):
sorted = np.sort(input)
result = []
for i, v1 in enumerate(sorted):
result.append([])
for j, v2 in enumerate(sorted):
if v2 - tol < v1 < v2 + tol:
result[i].append(v2)
result = [r for r in result if len(r) > 1]
for i, r1 in enumerate(result):
for j, r2 in enumerate(result):
if set(r2).issubset(set(r1)):
del result[j]
return result
test = np.array([2.6, 1.2, 1.5, 1.8, 2.0, 2.2, 2.5, 1.1, 1.4])
tolerance = 0.15
almost_equal = find_almost_equal(test, tolerance)
print(almost_equal)
结果是 .结果是.[[1.1, 1.2], [1.4, 1.5], [2.5, 2.6]]
tolerance = 0.25
[[1.1, 1.2, 1.4], [1.4, 1.5], [1.8, 2.0, 2.2], [2.5, 2.6]]
当一个点属于多个子列表时,我的算法并不总是给出正确的结果。例如,输入和输出是 ,而预期结果是 。[1.0, 1.1, 1.2, 1.3, 1.4]
tolerance = 0.2
[[1.0, 1.1, 1.2], [1.2, 1.3, 1.4]]
[[1.0, 1.1, 1.2], [1.1, 1.2, 1.3], [1.2, 1.3, 1.4]]
问题:有没有更简单的方法可以做到这一点(最好是在numpy中)?我怎样才能正确地做到这一点?
答:
1赞
Matt Pitkin
11/10/2023
#1
一种更简洁的方法,使用更多的 NumPy 功能,是进行一系列差异(如本答案所示),例如:
def find_almost_equal(inp, tol):
# create array of differences
inpa = np.sort(inp)
diff = np.abs(np.subtract.outer(inpa, inpa))
# get precision of float type
prec = np.finfo(inpa.dtype).eps * 10
# loop over rows in diff array (except first and last)
l = []
for row in diff[1:-1]:
# get values within tolerance (accounting for floating point precision)
r = inpa[row + prec < tol].tolist()
if len(r) > 1:
for i, prev in enumerate(l):
# make sure list isn't subset of previous lists
if set(r).issubset(prev):
break
elif set(prev).issubset(r):
# add in longer lists
del l[i]
l.append(r)
break
else:
l.append(r)
return l
这给出了:
find_almost_equal([2.6, 1.2, 1.5, 1.8, 2.0, 2.2, 2.5, 1.1, 1.4], 0.15)
[[1.1, 1.2], [1.4, 1.5], [2.5, 2.6]]
find_almost_equal([2.6, 1.2, 1.5, 1.8, 2.0, 2.2, 2.5, 1.1, 1.4], 0.25)
[[1.1, 1.2, 1.4], [1.2, 1.4, 1.5], [1.8, 2.0, 2.2], [2.5, 2.6]]
find_almost_equal([1.0, 1.1, 1.2, 1.3, 1.4], 0.2)
[[1.0, 1.1, 1.2], [1.1, 1.2, 1.3], [1.2, 1.3, 1.4]]
评论
tolerance = 0.25
[1.1, 1.2, 1.4]
1.4 - 1.1 > 0.25
max - min <= tolerance
x
c
c
1.1, 1.2, 1.3, 1.4, 1.5
tolerance = 0.15
tol = 10
test = [1,5,6,7,8,12]
[1,5,6,7,8]
[5,6,7,8,12]
([1,5,6], [7,8,12])