【发布时间】:2011-07-14 14:22:22
【问题描述】:
我正在寻找一种单通道算法,用于在我不知道提前总数的流中找到最高百分比的浮点数......但它大约为 5-30 百万个浮点数。它需要单次传递,因为数据是动态生成的,并且会再次重新创建准确的流。
到目前为止,我使用的算法是保留到目前为止我见过的 topX 项目的排序列表。随着流的继续,我会根据需要扩大列表。然后,如果需要,我使用bisect_left 来查找插入点。
以下是我目前的算法:
from bisect import bisect_left
from random import uniform
from itertools import islice
def data_gen(num):
for _ in xrange(num):
yield uniform(0,1)
def get_top_X_percent(iterable, percent = 0.01, min_guess = 1000):
top_nums = sorted(list(islice(iterable, int(percent*min_guess)))) #get an initial guess
for ind, val in enumerate(iterable, len(top_nums)):
if int(percent*ind) > len(top_nums):
top_nums.insert(0,None)
newind = bisect_left(top_nums, val)
if newind > 0:
top_nums.insert(newind, val)
top_nums.pop(0)
return top_nums
if __name__ == '__main__':
num = 1000000
all_data = sorted(data_gen(num))
result = get_top_X_percent(all_data)
assert result[0] == all_data[-int(num*0.01)], 'Too far off, lowest num:%f' % result[0]
print result[0]
在实际情况下,数据并非来自任何标准分布(否则我可以使用一些统计知识)。
任何建议将不胜感激。
【问题讨论】:
-
这个程序有效吗?问题是什么?要查看您的代码,请尝试Code Review
-
是的,它工作得很好(虽然很慢)......我想知道是否有人有任何更棘手的方法......我不知道代码审查......有没有迁移它的方法?
-
对于工作代码,最好试试Code Review 这个网站是 mor 对于不工作的代码
-
如果在迭代过程中的某个时刻,您存储了前 100 个项目,然后出现了一个小于第 100 个项目的项目,但不是很多。然后,稍后您扩展以存储 101 个项目,但是您丢弃的上一个项目现在比您现在看到的所有项目都大......换句话说,您丢弃了真正的第 101 个项目。这有意义吗?
-
@Lasse:这很有道理......也看不到任何方法。hmmm