在布告中找到最接近的值

时间:2021-05-16 21:27:30

So basically I have a dict with some values in it, and I want to find the closest value to the given one. So it would look something like this:

所以基本上我有一个包含一些值的命令,我想找到与给定值最近的值。大概是这样的:

values = {"val": [210418, 211120, 211822, 212523, 213500]}
input = 210944
output = find_nearest(input,values["val"])
print output
# 210418

and as you can see I want to get the closest value under my value. The min() method was giving me 211120, but I want to get 210418. How can I do this?

你可以看到,我想在我的值下得到最接近的值。min()方法是给我211120,但我想要得到210418。我该怎么做呢?

5 个解决方案

#1


2  

If your values are ordered, like in the example data, this is possible in logarithmic time using bisection:

如果您的值是有序的,比如在示例数据中,这在使用bisection的对数时间是可能的:

>>> vals = [210418, 211120, 211822, 212523, 213500]
>>> target = 210944
>>> from bisect import bisect_left
>>> i = bisect_left(vals, target)
>>> if i == 0:
...     raise Exception
... 
>>> vals[i-1]
210418

If they are not ordered, consider numpy:

如果没有排序,考虑numpy:

>>> import numpy as np
>>> a = np.array(vals)
>>> a[a<target].max()
210418

#2


1  

Use abs(a - b) as absolute difference (distance) between two values, and pass that as lambda to key argument of min function.

使用abs(a - b)作为两个值之间的绝对差(距离),并将其传递给min函数的关键参数。

  def find_nearest(val, arr):
        return min(arr, key=lambda a: abs(val - a))

#3


1  

You can try this:

你可以试试这个:

values = {"val": [210418, 211120, 211822, 212523, 213500]}
input = 210944
final_value = [i for i in sorted(values['val'], key=lambda x:abs(x-input)) if i < input][0]

Output:

输出:

210418

#4


1  

Here is your solution. This runs in O(n) time.

这是您的解决方案。它在O(n)时间内运行。

In [20]: values = {"val": [210418, 211120, 211822, 212523, 213500]}
    ...:

In [21]: list_val = values['val']

In [22]: def nearest_val(val):
    ...:     nearest = list_val[0]
    ...:     for v in list_val[1:]:
    ...:         if v == val:
    ...:             nearest = val
    ...:             break
    ...:         if v-val > 0 and v-val < nearest-val:
    ...:             nearest = v
    ...:     return nearest
    ...:

In [23]: nearest_val(210944)
Out[23]: 210418

First sort the "val" list, then loop over the sorted list and keep checking if you have found a value smaller than the nearest calculated till now.

首先对“val”列表进行排序,然后对排序后的列表进行循环,并继续检查是否找到了一个小于最近计算值的值。

#5


0  

You want the the value x whose positive difference input - x is minimized. Values for which input - x is negative can be ignored by letting their key value be input, which is by definition larger than input - x. Only

你想要的是x的值它的输入- x是最小的。输入- x为负的值可以通过让它们的键值为input来忽略,根据定义,这个值要大于输入- x

output = min(values['val'], key=lambda x: input - x if x < input else input)

If no value is less than input, min will raise a ValueError on the resulting empty sequence. I leave it as an exercise for the reader to decide how to handle that.

如果没有任何值小于输入,min将在结果的空序列上增加一个ValueError。我把它作为一个练习留给读者来决定如何处理它。

#1


2  

If your values are ordered, like in the example data, this is possible in logarithmic time using bisection:

如果您的值是有序的,比如在示例数据中,这在使用bisection的对数时间是可能的:

>>> vals = [210418, 211120, 211822, 212523, 213500]
>>> target = 210944
>>> from bisect import bisect_left
>>> i = bisect_left(vals, target)
>>> if i == 0:
...     raise Exception
... 
>>> vals[i-1]
210418

If they are not ordered, consider numpy:

如果没有排序,考虑numpy:

>>> import numpy as np
>>> a = np.array(vals)
>>> a[a<target].max()
210418

#2


1  

Use abs(a - b) as absolute difference (distance) between two values, and pass that as lambda to key argument of min function.

使用abs(a - b)作为两个值之间的绝对差(距离),并将其传递给min函数的关键参数。

  def find_nearest(val, arr):
        return min(arr, key=lambda a: abs(val - a))

#3


1  

You can try this:

你可以试试这个:

values = {"val": [210418, 211120, 211822, 212523, 213500]}
input = 210944
final_value = [i for i in sorted(values['val'], key=lambda x:abs(x-input)) if i < input][0]

Output:

输出:

210418

#4


1  

Here is your solution. This runs in O(n) time.

这是您的解决方案。它在O(n)时间内运行。

In [20]: values = {"val": [210418, 211120, 211822, 212523, 213500]}
    ...:

In [21]: list_val = values['val']

In [22]: def nearest_val(val):
    ...:     nearest = list_val[0]
    ...:     for v in list_val[1:]:
    ...:         if v == val:
    ...:             nearest = val
    ...:             break
    ...:         if v-val > 0 and v-val < nearest-val:
    ...:             nearest = v
    ...:     return nearest
    ...:

In [23]: nearest_val(210944)
Out[23]: 210418

First sort the "val" list, then loop over the sorted list and keep checking if you have found a value smaller than the nearest calculated till now.

首先对“val”列表进行排序,然后对排序后的列表进行循环,并继续检查是否找到了一个小于最近计算值的值。

#5


0  

You want the the value x whose positive difference input - x is minimized. Values for which input - x is negative can be ignored by letting their key value be input, which is by definition larger than input - x. Only

你想要的是x的值它的输入- x是最小的。输入- x为负的值可以通过让它们的键值为input来忽略,根据定义,这个值要大于输入- x

output = min(values['val'], key=lambda x: input - x if x < input else input)

If no value is less than input, min will raise a ValueError on the resulting empty sequence. I leave it as an exercise for the reader to decide how to handle that.

如果没有任何值小于输入,min将在结果的空序列上增加一个ValueError。我把它作为一个练习留给读者来决定如何处理它。