Python:如何在两个单独的数组之间找到两个相等/最接近的值?
假设我们有两个长度相等的数组:Python:如何在两个单独的数组之间找到两个相等/最接近的值?,python,comparison,Python,Comparison,假设我们有两个长度相等的数组: arr1 = (21, 2, 3, 5, 13) arr2 = (10, 4.5, 9, 12, 20) 来自arr1的哪个变量与来自arr2的变量相等/最接近 看看这两个列表,我们可以很容易地说,最接近的数字是4.5和5。我试着实现一个函数,在给定两个列表的情况下返回两个最接近的值,它对上面的例子有点有效,但它几乎不是一个解决方案,因为它不是最优的。当我们稍微更改数组时,您可以很容易地检查函数是否失败,如下所示: arr1 = (21, 2, 3, 5, 13
arr1 = (21, 2, 3, 5, 13)
arr2 = (10, 4.5, 9, 12, 20)
来自arr1
的哪个变量与来自arr2
的变量相等/最接近
看看这两个列表,我们可以很容易地说,最接近的数字是4.5和5。我试着实现一个函数,在给定两个列表的情况下返回两个最接近的值,它对上面的例子有点有效,但它几乎不是一个解决方案,因为它不是最优的。当我们稍微更改数组时,您可以很容易地检查函数是否失败,如下所示:
arr1 = (21, 2, 3, 5, 13)
arr2 = (10, 4.5, 9, 12, 18)
函数返回的值是13和18
以下是函数:
def get_nearest(arr1, arr2):
lr = [[0, 0, 0]]
for x1 in arr1:
for x2 in arr2:
r = (x1 / x2 % (x1 + x2))
print x1, x2, r
if r <= 1 and r >= lr[0][2]:
lr.pop()
lr.append([x1, x2, r])
return lr
def get_nearest(arr1,arr2):
lr=[[0,0,0]]
对于arr1中的x1:
对于arr2中的x2:
r=(x1/x2%(x1+x2))
打印x1、x2、r
如果r=lr[0][2]:
lr.pop()
lr.追加([x1,x2,r])
返回lr
你能想出一个更好的吗?速度是个问题吗?你在乎领带吗?如果不是,那么像这样简单的事情呢
from itertools import product
sorted(product(arr1, arr2), key=lambda t: abs(t[0]-t[1]))[0]
两者皆有
arr1 = (21, 2, 3, 5, 13)
arr2 = (10, 4.5, 9, 12, 20)
及
这就产生了
(5, 4.5)
说明:
product(arr1, arr2) = [(a1, a2) for (a1, a2) in product(arr1, arr2)]
生成所有N**2
对数字的列表:
[(21, 10), (21, 4.5), ..., (13, 12), (13, 20)]
然后我们使用排序后的按绝对差(|a1-a2 |
)对它们进行排序。通过传递sorted
关键字key
,我们告诉sorted
使用排序标准lambda t:abs(t[0]-t[1])
。绝对差最小的一对放在排序数组的第一个索引中,因此我们可以通过在末尾添加[0]
来获取它
编辑:
product(arr1, arr2) = [(a1, a2) for (a1, a2) in product(arr1, arr2)]
正如Piotr在评论中所建议的那样,您可以将key=func
输入到min
和max
,这大大加快了速度。请尝试:
from itertools import product
min(product(arr1, arr2), key=lambda t: abs(t[0]-t[1]))[0]
一种简单的方法是获取两个数组之间的差异,并根据它们的差异对它们进行排序,然后获取第一个元素
>>> sorted([[a1,a2,a1-a2] if(a1>a2) else [a1,a2,a2-a1] for a1 in arr1 for a2 in arr2], key=lambda i:i[-1])[0][:2]
[5, 4.5]
在每次迭代中保存差异和值怎么样
arr1 = (21, 2, 3, 5, 13)
arr2 = (10, 4.5, 9, 12, 20)
diff = float("inf")
for a1 in arr1:
for a2 in arr2:
if abs(a1-a2) < diff:
diff = abs(a1-a2)
values = (a1, a2)
print(values)
arr1=(21,2,3,5,13)
arr2=(10,4.5,9,12,20)
差异=浮动(“inf”)
对于arr1中的a1:
对于arr2中的a2:
如果abs(a1-a2)
这是我能写的最快的算法,它有n*log(n)复杂度,比其他答案中给出的简单n*n方法快得多。它在处理之前对数组进行排序(这是最耗时的部分),然后尝试最小化差异(在最坏的情况下需要2*n):
def最近的_数组_项(a1、a2):
如果不是a1或a2:
raise VALUERROR('空数组')
a1,a2=国际热核实验堆(分类(a1)),国际热核实验堆(分类(a2))
i1,i2=a1.next(),a2.next()
min_dif=浮点('inf')
而1:
dif=abs(i1-i2)
如果dif<最小dif:
min_dif=dif
配对=i1,i2
如果不是最小值:
打破
如果i1>i2:
尝试:
i2=a2.next()
除停止迭代外:
打破
其他:
尝试:
i1=a1.next()
除停止迭代外:
打破
返回对
这里有一个函数,对于长度为1000、2000的两个向量,它在~0.01秒内解决了这个问题:
def get_closest_elements(arr_1, arr_2):
"""
The function finds the two closest elements in two arrays
Returns
-------
idx_1 : int
index of element in arr_1
idx_2 : int
index of element in arr_2
min_diff : float
minimal difference between arrays
"""
# get array with all differences between arrays
diff_arr = x[:, np.newaxis] - y
# get absolute value
diff_arr = np.abs(diff_arr)
# get minimum difference
min_diff = np.min(diff_arr)
# get the indexes for the elements of interest in arr_1 and arr_2
idx_1, idx_2 = np.where(diff_arr == min_diff)
return idx_1, idx_2, min_diff
# apply function
x = np.array([21, 2, 3, 5, 13])
y = np.array([10, 4.5, 9, 12, 20])
# n = 1000
# x = np.random.rand(n)
# y = np.random.rand(2*n)
idx_1, idx_2, min_diff = get_closest_elements(x, y)
print "x{} - y{} = {}".format(idx_1, idx_2, min_diff)
对我来说,它似乎是5和4.5最接近?你是对的,我的错误确实很好,但我需要一些时间来理解这里发生了什么。@minerals,我添加了一个解释。你应该使用max而不是sorted()[0]
def closest_array_items(a1, a2):
if not a1 or not a2:
raise ValueError('Empty array')
a1, a2 = iter(sorted(a1)), iter(sorted(a2))
i1, i2 = a1.next(), a2.next()
min_dif = float('inf')
while 1:
dif = abs(i1 - i2)
if dif < min_dif:
min_dif = dif
pair = i1, i2
if not min_dif:
break
if i1 > i2:
try:
i2 = a2.next()
except StopIteration:
break
else:
try:
i1 = a1.next()
except StopIteration:
break
return pair
def get_closest_elements(arr_1, arr_2):
"""
The function finds the two closest elements in two arrays
Returns
-------
idx_1 : int
index of element in arr_1
idx_2 : int
index of element in arr_2
min_diff : float
minimal difference between arrays
"""
# get array with all differences between arrays
diff_arr = x[:, np.newaxis] - y
# get absolute value
diff_arr = np.abs(diff_arr)
# get minimum difference
min_diff = np.min(diff_arr)
# get the indexes for the elements of interest in arr_1 and arr_2
idx_1, idx_2 = np.where(diff_arr == min_diff)
return idx_1, idx_2, min_diff
# apply function
x = np.array([21, 2, 3, 5, 13])
y = np.array([10, 4.5, 9, 12, 20])
# n = 1000
# x = np.random.rand(n)
# y = np.random.rand(2*n)
idx_1, idx_2, min_diff = get_closest_elements(x, y)
print "x{} - y{} = {}".format(idx_1, idx_2, min_diff)