我们在Python中说我有一个各自大小的文件列表,表示为dict(我不关心结构,你可以提出另一个):
from random import randint
def gen_rand_fileslist(nbfiles=100, maxvalue=100):
fileslist = {}
for i in xrange(nbfiles):
fileslist["file_"+str(i)] = randint(1, maxvalue)
return fileslist
fileslist = gen_rand_fileslist(10)
示例fileslist
:
{'file_0': 2,
'file_1': 21,
'file_2': 20,
'file_3': 16,
'file_4': 12,
'file_5': 67,
'file_6': 95,
'file_7': 16,
'file_8': 2,
'file_9': 5}
现在我想快速找到低于指定阈值的最高值。例如:
get_value_below(fileslist, threshold=25) # result should be 'file_1' with value 21
函数get_value_below()将在紧密循环中调用,因此它应该尽可能快,并且可以指定任何阈值(因此排序不会直接帮助)。
有没有办法比仅仅遍历整个列表(线性时间)更快?
答案 0 :(得分:3)
这完全取决于您在fileslist
中搜索阈值的频率。如果您要执行的不仅仅是Θ(log n)
次查询,那么最好先排序,然后对每个查询执行二进制搜索。否则,如果你只想执行一个查询,那么是线性搜索更好,因为你想要的元素几乎可以在任何地方,你肯定需要访问列表中的每个元素。
如果您计划先使用排序,然后使用二进制搜索,那么使用bisect_right作为输入x
,它将返回列表中包含最大元素低于或等于的位置到x
。
答案 1 :(得分:1)
我建议使用pandas DataFrame,它可以快速解决您的搜索问题。
考虑以下示例:
0
21 file_1
<强> OUT:强>
np.nonzero(sorted<=x)[0]
不要线性搜索已排序的数组,使用二进制搜索(duh)。一方面,这是CS 101孩子的东西。另一方面,我不知道bisect库,并且代码中充满了(function() {
'use strict';
angular
.module('antApp')
.controller('StartMenuController', StartMenuController);
function StartMenuController($scope, $rootScope, $state){
var self = $scope;
self.app = $rootScope;
self.init = init;
self.startGame = startGame;
init();
function init(){
};
function startGame (){
$state.go('main');
};
};
。一旦我切换到使用bisect_left / bisect_right,我看到了巨大的性能提升。编辑:在评论中,Peter指出NumPy实现了一个更快的二进制搜索,名为searchsorted;你(和我)可能应该使用它!。
来自http://docs.pylonsproject.org/projects/colander/en/latest/binding.html#what-is-schema-binding的一些有用的引用:
韦斯麦金尼是个天才。如果你正在实施Wes McKinney已经放入他的图书馆熊猫的任何东西,那就停下来吧。他的代码比你要编写的任何内容更快,更强大,更可能更正确。想滚动窗口聚合器?使用熊猫。需要处理丢失的数据吗?使用熊猫。你是在编写某种令人难以置信的丑陋黑客,试图在NumPy阵列上实现连接和分组,但实际上却花了3个小时来计算一个微妙的错误结果? (我已经这样做了)。耶稣基督,停止并使用大熊猫。