【问题标题】:Given a float, find if in list or closest number to it给定一个浮点数,查找是否在列表中或最接近它的数字
【发布时间】:2014-04-22 05:48:59
【问题描述】:

我有一个元组列表,即具有 x 和 y 值的 2-dim 元组。称之为数据。我想取两个浮点数,xmin 和 xmax,并返回该间隔上最大 y 值的索引。 即使 xmin 和 xmax 与数据点不完全匹配,它也应该可以工作。

除了将 xmin 和 xmax 舍入到列表中最接近的值之外,我了解如何解决此问题。我不知道,因为我是 python 新手。

# Find the index of the point (x, y) with the maximum y value
# on the interval [xmin, xmax]
def find_peak(data, xmin, xmax):

暂时,我可以搜索列表并记录每个 x 值的最小差异。这可行还是有更聪明的方法?

【问题讨论】:

    标签: python list


    【解决方案1】:

    给定一个二维坐标列表。

    1. 根据 x 坐标对数据进行排序。这应该是自然列表排序。
    2. 使用pythonbisect模块确定数据点的开始和结束索引
    3. 使用内置的min,键为operator.itemgetter(1),查找x_main和x_max中y值最大的元素

    示例实施

    def foo(data, x_min, x_max):
        from bisect import bisect_left, bisect
        from operator import itemgetter
        data = sorted(data)
        x_data = [x for x,y in data]
        index_min = bisect_left(x_data, x_min)
        index_max = bisect(x_data, x_max)
        return max(data[index_min:index_max],key=itemgetter(1))[-1]
    

    示例运行

    >>> data = [(random.randint(1,20),random.randint(1,20)) for _ in range(10)]
    >>> data
    [(9, 9), (11, 11), (7, 7), (16, 11), (15, 19), (8, 18), (16, 3), (18, 7), (17, 13), (3, 11)]
    >>> foo(data,3,7)
    11
    

    【讨论】:

    • 这是什么操作? x_data = [x for x,y in data]
    • @alvarezcl:这是一个列表理解。这将返回一个包含数据点内所有 x 坐标的列表。不幸的是 bisect 模块没有自定义键功能,因此您必须添加额外的开销。但是,请记住,即使有开销,考虑到复杂度的顺序是 O(nlog(n)) 并且在任何复杂计算中都没有开销,这个实现也会非常快。
    • 如果xmax 小于data 中的最小x 值,则此答案中的代码会引发ValueErrorreturn 语句应该嵌套在try 语句中。
    【解决方案2】:
    max_finder = lambda point: point[1] if x_min <= point[0] <= x_max else float("-inf")
    # get data point of target element
    max_y = max(data, key=max_finder)
    
    # gets index of target element
    max_y_idx = max(enumerate(data), key=lambda x: max_finder(x[1]))[0]
    # or alternatively, after finding max_y
    max_y_idx = data.index(max_y_idx)
    

    请注意,与 O(n*log(n)) 排序复杂度相比,max 的复杂度为 O(n),index 的最坏情况复杂度为 O(n),因此这应该稍微优于排序变体。

    有关详细信息,请参阅 maxenumerate 文档

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      • 1970-01-01
      • 2019-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-11
      相关资源
      最近更新 更多