Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 理解使用堆从整数流中获取平均值_Python_Algorithm_Heap - Fatal编程技术网

Python 理解使用堆从整数流中获取平均值

Python 理解使用堆从整数流中获取平均值,python,algorithm,heap,Python,Algorithm,Heap,我关注下面的博客,了解如何以一种非常微妙的方式获得中间值。这个博客是 现在,我将下面的函数添加到streamMedian类中,以获得插入的数字的平均值,而不是所需的输出 import heapq class streamMedian: def __init__(self): self.minHeap, self.maxHeap = [], [] self.N=0 def insert(self, num): if self.N

我关注下面的博客,了解如何以一种非常微妙的方式获得中间值。这个博客是

现在,我将下面的函数添加到streamMedian类中,以获得插入的数字的平均值,而不是所需的输出

import heapq

class streamMedian:
    def __init__(self):
        self.minHeap, self.maxHeap = [], []
        self.N=0


    def insert(self, num):
        if self.N%2==0:
            heapq.heappush(self.maxHeap, -1*num)
            self.N+=1
            if len(self.minHeap)==0:
                return
            if -1*self.maxHeap[0]>self.minHeap[0]:
                toMin=-1*heapq.heappop(self.maxHeap)
                toMax=heapq.heappop(self.minHeap)
                heapq.heappush(self.maxHeap, -1*toMax)
                heapq.heappush(self.minHeap, toMin)
        else:
            toMin=-1*heapq.heappushpop(self.maxHeap, -1*num)
            heapq.heappush(self.minHeap, toMin)
            self.N+=1

    def getMedian(self):
        if self.N%2==0:
            return (-1*self.maxHeap[0]+self.minHeap[0])/2.0
        else:
            return -1*self.maxHeap[0]

    def getMean(self):
        sum = 0
        for num in self.maxHeap:
            sum += num
        for num in self.minHeap:
            sum += num 
        return sum/self.N
这是对streamMedian类的函数调用

test = streamMedian()
test.insert(1)
test.insert(2)
test.insert(3)
print test.getMedian()
print test.getMean()

这里的中位数应该是2,平均值应该是2(而不是0是输出)。提前谢谢

您正在将负数推送到您的
maxHeap
-1*num
)。 您需要在
getMean()
中反转该选项,例如:

def getMean(self):
    total = 0
    for num in self.maxHeap:
        total -= num
    for num in self.minHeap:
        total += num 
    return total/self.N
或者:

def getMean(self):
    return (abs(sum(self.maxHeap)) + sum(self.minHeap))/self.N

注意:不要使用
sum
作为变量,因为它隐藏了python内置的
sum()
函数

您正在将负数推送到您的
maxHeap
-1*num
)。 您需要在
getMean()
中反转该选项,例如:

def getMean(self):
    total = 0
    for num in self.maxHeap:
        total -= num
    for num in self.minHeap:
        total += num 
    return total/self.N
或者:

def getMean(self):
    return (abs(sum(self.maxHeap)) + sum(self.minHeap))/self.N

注意:不要使用
sum
作为变量,因为它隐藏了python内置的
sum()
函数

AChampion的回答正确地识别了当前代码的问题,并在仍然使用当前算法的情况下提供了合理的修复。但是,该算法不是很有效(需要
O(N)
时间),您可以做得更好

具体地说,除了将插入的值推送到某个堆上之外,还应该将插入的值添加到累积总和中。这样,当您需要获得平均值时,您可以在恒定时间内计算它(只需一次除法):


请注意,如果您使用的是Python 2(看起来您是这样的),则使用浮点值
0.0
而不是整数
0
初始化
cumulative_sum
非常重要。在Python2中,当您除以两个整数时,您将得到另一个整数,向下舍入。如果您正在计算
1
2
的平均值(您期望
1.5
,但如果您只进行
(1+2)/2
,您将得到
1
)。Python3做得更好(您总是从常规除法中得到一个浮点,并且可以使用
/
操作符显式请求“floor”除法)。如果您想在Python 2中获得相同的语义,可以将来自“未来”导入分部的
放在模块顶部。

AChampion的回答正确地识别了当前代码的问题,并在仍然使用当前算法的情况下提供了合理的修复。但是,该算法不是很有效(需要
O(N)
时间),您可以做得更好

具体地说,除了将插入的值推送到某个堆上之外,还应该将插入的值添加到累积总和中。这样,当您需要获得平均值时,您可以在恒定时间内计算它(只需一次除法):


请注意,如果您使用的是Python 2(看起来您是这样的),则使用浮点值
0.0
而不是整数
0
初始化
cumulative_sum
非常重要。在Python2中,当您除以两个整数时,您将得到另一个整数,向下舍入。如果您正在计算
1
2
的平均值(您期望
1.5
,但如果您只进行
(1+2)/2
,您将得到
1
)。Python3做得更好(您总是从常规除法中得到一个浮点,并且可以使用
/
操作符显式请求“floor”除法)。如果您想在Python 2中获得相同的语义,可以将来自未来导入部门的
放在模块顶部。

应编辑
(1+2+3)/3==2
。谢谢
平均值应
(1+2+3)/3==2
编辑。谢谢你,这不是仍然是
O(n)
只是分散在每个插入上吗?就像你仍然在为每个
O(n)
项目执行
+=
操作一样。不同之处在于每次调用
getMean()
,只调用
O(n)
一次(或者使用流式计算没有意义)。如果你调用
getMean
O(n)
次,那么每次调用的值加起来的成本会分摊到
O(1)
。这不是仍然
O(n)
只是分散在每个插入上吗?就像你仍然在为
O(n)
的每个项目执行
+=
操作一样。不同之处在于每次调用
getMean()
,只调用
O(n)
一次(或者使用流式计算没有意义)。如果调用
getMean
O(n)
次,则每次调用的值相加成本将摊销到
O(1)