我有两个不同长度的列表。示例---
E1 = [1.0,1.3,1.69,2.1970,2.8561,.....]
和
E2 = [1.00,1.04,1.08,1.1249,1.1699,.....]
(当然E2的元素数量多于E1)。现在我想将E1列表与E2进行比较,找到最接近E1中每个元素的值,例如E1中的1.3最接近E2中的1.1699。类似地,我想对E1中的所有其他元素执行此操作...因此,如果我从E2中创建新的列表E3,那将包含与E1最接近的元素数量和最接近E1元素的值。我怎样才能做到这一点 ?任何帮助表示赞赏..
答案 0 :(得分:2)
快速而肮脏的版本:
E3 = [min(E2, key=lambda x: abs(x-i)) for i in E1]
对于E1
中的每个元素,它根据与E2
元素的绝对距离找到E1
的最小元素。
请注意,此列表将包含重复项。例如。例如,它返回:
[1.0, 1.1699, 1.1699, 1.1699, 1.1699]
因为1.1699最接近E1
中的所有较大值。
线性时间,但对于排序列表更复杂的解决方案:
E3 = []
p2 = 0
for e1 in E1:
while p2 < len(E2) - 1 and abs(E2[p2] - e1) > abs(E2[p2+1] - e1):
p2 += 1
E3.append(E2[p2])
答案 1 :(得分:2)
让我向您介绍一个非常了不起的Python模块bisect
。
import bisect
def find_nearest(refsort, pt):
loc = bisect.bisect_left(refsort, pt)
if loc >= len(refsort)-1:
# Value greater than all elements of refsort
return refsort[-1]
d1 = pt - refsort[i]
d2 = refsort[i+1] - pt
if d1 < d2:
return refsort[i]
else:
return refsort[i+1]
def replace_with_nearest(ptlist, reflist):
''' Replace every point in ptlist with the nearest value from reflist '''
refsort = sorted(reflist) # omit if you know reflist is sorted
return [find_nearest(refsort, pt) for pt in ptlist]
E3 = replace_with_nearest(E1, E2)
假设数组已排序, bisect
使用经典数组平分技术在O(log n)
时间内找到小于给定输入的最大数组元素。我们使用它来定位两个值,这两个值立即小于和大于E2
的每个元素。
这在O(n log k)时间内运行,其中n
是E2的长度,k
是E1的长度(假设n> k)。请注意,E2不需要排序。
答案 2 :(得分:0)
def closest(num, lst):
ret = lst[0]
dist = abs(lst[0]-num)
for n in lst:
if abs(n-num) < dist:
dist = abs(n-num)
ret = n
return ret
e1 = [1.0,1.3,1.69,2.1970,2.8561]
e2 = [1.00,1.04,1.08,1.1249,1.1699]
e3 = [closest(n, e2) for n in e1]
print(e3)
[1.0, 1.1699, 1.1699, 1.1699, 1.1699]