【问题标题】:binary search for multiple values对多个值进行二分搜索
【发布时间】:2014-03-02 01:00:36
【问题描述】:

您好,我有一个与 python 相关的问题,

我有一个排序的 Numpy 数组,我必须快速找到某些值的索引,到目前为止我一直在使用二进制搜索,但我遇到的问题是有许多相同值的条目,我必须找到所有值的索引。有没有办法修改二进制搜索以找到全部?
当前代码是

def binarySearch(alist,item,con_array,element):
    if len(alist) == 0:
        return False
    else:
        midpoint = len(alist)//2
        if alist[midpoint]==item:            
            for l in range(len(alist)):
                if alist[l] == item:
                    n_array.append(con_array[l])
            return True                   
        else:
            if item<alist[midpoint]:
                return binarySearch(alist[:midpoint],item,con_array[:midpoint],i)
            else:
                return binarySearch(alist[midpoint+1:],item,con_array[midpoint+1:],i) 

如您所见,我尝试通过简单地搜索缩短的数组来合并它,但这仍然会删除一些值

【问题讨论】:

  • 当前代码没有运行,说缩进被破坏了
  • 你需要找到多少个值?如果您需要查找多个值,二分查找可能不是最佳选择。
  • 在一个大约有 1,000,000 个条目的数组中最多 15 个不少于 4 个

标签: python search numpy binary binary-search-tree


【解决方案1】:

二分搜索可以很容易地找到大于键的第一个值,因此通过两次搜索,您可以找到等于键的值范围。 NumPy 实际上已经为你实现了:

>>> a = np.array([0, 1, 2, 2, 2, 3, 5, 7])
>>> left = np.searchsorted(a, 2, side='left')
>>> right = np.searchsorted(a, 2, side='right')
>>> a[left:right]
array([2, 2, 2])

对于非常大的数组,在a[left:] 上执行第二次搜索可能会更有效:

>>> right = left + np.searchsorted(a[left:], 2, side='right')
>>> a[left:right]
array([2, 2, 2])

【讨论】:

  • 嗨,感谢您的回复,这看起来很有趣,但我是我正在寻找的值的索引,无论如何修改它以输出索引?
  • 该方法运行良好,唯一的问题是它对我的其他方法的压缩速度非常慢(尽管我的方法无法正常工作)速度是此应用程序的主要因素
  • @user2957178 我觉得这很难相信。你有基准数据吗?
【解决方案2】:

调整二分搜索来做到这一点是一项非常有教育意义的练习,当我教授算法时,我总是建议我的学生尝试一下。如果您只想完成它,numpy 已经有一个功能可以满足您的需求:

import numpy as np
a = np.array([1,2,3,1,2,3,1,1])
np.where(a==1)

哪个输出

(array([0, 3, 6, 7]),)

【讨论】:

  • 即使在这么少量的数据上,调用np.searchsorted 两次也比np.where 快(不计算排序成本)。在 10000 个元素时,速度要快一个数量级。
  • 同意。没想到searchsorted
  • 这不是二分查找,而是线性查找。这就是 np.where 慢得多的原因。
猜你喜欢
  • 2020-08-23
  • 2015-04-01
  • 2017-02-10
  • 1970-01-01
  • 2015-12-04
  • 2010-12-25
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多