知道Python有一个heapq
模块可以让你保持一个可迭代的运行“最小值”,我做了一个搜索heapq
and median
,并找到了各种项目steaming medium
。这个:
http://www.ardendertat.com/2011/11/03/programming-interview-questions-13-median-of-integer-stream/ http://www.ardendertat.com/2011/11/03/programming-interview-questions-13-median-of-integer-stream/
has a class streamMedian
维持两个heapq
,一个包含值的下半部分,另一个包含值的上半部分。中位数是其中一个值的“最高值”,或者是两个值的平均值。班级有一个insert
方法和一个getMedian
方法。大部分工作都在insert
.
我将其复制到 Ipython 会话中,并定义:
def cummedian_stream(b):
S=streamMedian()
ret = []
for item in b:
S.insert(item)
ret.append(S.getMedian())
return np.array(ret)
Testing:
In [155]: a = np.random.randint(0,100,(5000))
In [156]: amed = cummedian_stream(a)
In [157]: np.allclose(cummedian_sorted(a), amed)
Out[157]: True
In [158]: timeit cummedian_sorted(a)
1 loop, best of 3: 781 ms per loop
In [159]: timeit cummedian_stream(a)
10 loops, best of 3: 39.6 ms per loop
The heapq
流方法要快得多。
列表理解@Uriel
给的比较慢。但如果我替代np.median
for statistics.median
它比@Divakar's
排序解决方案:
def fastloop(a):
return np.array([np.median(a[:i+1]) for i in range(len(a))])
In [161]: timeit fastloop(a)
1 loop, best of 3: 360 ms per loop
And @Paul Panzer's
分区方法也不错,但与流式传输类相比仍然很慢。
In [165]: timeit cummedian_partition(a)
1 loop, best of 3: 391 ms per loop
(我可以复制streamMedian
如果需要的话,可以对此答案进行分类)。