Python-while真循环中三个值的平均值

时间:2019-05-28 09:30:02

标签: python

我正在使用距离传感器在树莓派上开发python脚本。 我的代码可以正常工作,并且可以达到一定距离,但是我想避免出现一些误报/误报,因此我想获取最后三个数据的平均值。

这是我的代码:

while True:
        distance= misura() # GETTING THE REAL DISTANCE IN CM
        print "Distanza : %.2f" % distanza

        avg_distance = <something> # <- HERE I NEED SOMETHING ELEGANT

        if (avg_distance > 30):
            print "NOT PRESENT"
        else:
            print "PRESENT"

        time.sleep(1.5)

我想要一些函数(也许基于列表?),该函数返回最近三个(或n个)距离的平均值

重要 : 我不想存储所有值,因为此脚本将运行几天又几天

9 个答案:

答案 0 :(得分:3)

我会使用collections.deque

from collections import deque
SAMPLE = 3
data = deque(maxlen=SAMPLE)
while True:
    distance = misura() # GETTING THE REAL DISTANCE IN CM
    print "Distanza : %.2f" % distanza

    data.append(distance)
    avg_distance = sum(data)/SAMPLE # <- HERE I NEED SOMETHING ELEGANT

    ... # rest as before

双端队列的长度是固定的,因此您只采样最近的三个。如果要更改采样周期,只需更改一个变量即可。

如果要在一个紧密的循环中运行此循环(即,删除1.5s睡眠),则可以将总和保存在变量中,以在每个循环中除去O(n)操作(即使这并不是真正的问题)仅3个元素)。像这样:

total -= data.popleft()
total += distance

data.append(distance)
average = total / 3 

答案 1 :(得分:2)

如果您的目标是仅记住最后三个测量并找到它们的平均值,请考虑使用collections.deque对象,这样当您添加到该对象时,它只会记住添加到其中的最后三个元素它。您可以在每次迭代中找到双端队列中内容的平均值:

from collections import deque
l = deque(maxlen=3) # New
while True:
    distance= misura() # GETTING THE REAL DISTANCE IN CM
    print "Distanza : %.2f" % distanza
    l.append(distance) # New
    #avg_distance = <something> # <- HERE I NEED SOMETHING ELEGANT
    avg_distance = sum(l) / len(l) # Compute average of the last three eleemnts

    if (avg_distance > 30):
        print "NOT PRESENT"
    else:
        print "PRESENT"

    time.sleep(1.5)

这样做的好处是,当双端队列已满并且您在其中附加了一个项目时,它将删除双端队列中最早添加的元素,并添加您要添加​​的最新元素。

答案 2 :(得分:0)

好吧,您可能只需要创建一个列表,例如 list = [misura(),misura(),misura()]分别获取三个值,并将其传递给类似的函数

def mean(list) :
    Total = 0
    For item in list :
        Total += item
    Return total /len(list)

答案 3 :(得分:0)

您可以利用以下事实:可变默认参数仅创建一次,以存储最后测得的三个值:

def last_three_average(val, last_three=[]):
    last_three.append(val)
    last_three = last_three[-3:]
    return sum(last_three) / len(last_three)

for idx in range(1, 10, 1):
    print(f'{idx}: {last_three_average(idx)}')

输出:

1: 1.0
2: 1.5
3: 2.0
4: 3.0
5: 4.0
6: 5.0
7: 6.0
8: 7.0
9: 8.0

或者,使用双端队列输入/输出列表:

from collections import deque

def last_three_average(val, last_three=deque(maxlen=3)):
    last_three.append(val)
    return sum(last_three) / len(last_three)

答案 4 :(得分:0)

您可以应用一些数学运算,并在每次新迭代中重新计算平均值。

passed = 0
avg_distance = 0
while True:
    passed += 1
    distance = misura()
    print("Distanza : %.2f" % distanza)

    avg_distance = ((passed - 1) * avg_distance + distance) / passed

    if (avg_distance > 30):
        print("NOT PRESENT")
    else:
        print("PRESENT")

    time.sleep(1.5)

答案 5 :(得分:0)

如果类型(距离)是一个列表,那么您可以简单地计算出最后3点的平均值,

distance = distance[-3:] # This will remove the extra data and get only last 3 values

average = sum(distance) / len(distance)

答案 6 :(得分:0)

首先创建一个列表(循环外):

distances = [misura(),misura(),misura()]

然后您的循环应如下所示:

while True:
    distances.append(misura())
    print "Distanza : %.2f" % distances[-1]

    distances = distances[1:] # this way you keep only the last 3 values
    avg_distance = sum(distances) / len(distances)

    if (avg_distance > 30):
        print "NOT PRESENT"
    else:
        print "PRESENT"

    time.sleep(1.5)

答案 7 :(得分:0)

查看另一个版本,其逻辑是仅在一个循环中保存3个元素即可。最后一个值是“弹出”,所以我们只有3个元素。

我下面的模型;

distancedata=[0,0,0]
for i in range(20):
        if len(distancedata) >= 3: 
            a=distancedata.pop(0)
        distancedata.append(float(i))
        print i,  distancedata,sum(distancedata) / len(distancedata)

结果在这里:

0 [0, 0, 0.0] 0.0
1 [0, 0.0, 1.0] 0.333333333333
2 [0.0, 1.0, 2.0] 1.0
3 [1.0, 2.0, 3.0] 2.0
4 [2.0, 3.0, 4.0] 3.0
5 [3.0, 4.0, 5.0] 4.0
6 [4.0, 5.0, 6.0] 5.0
7 [5.0, 6.0, 7.0] 6.0
8 [6.0, 7.0, 8.0] 7.0
9 [7.0, 8.0, 9.0] 8.0
10 [8.0, 9.0, 10.0] 9.0
11 [9.0, 10.0, 11.0] 10.0
12 [10.0, 11.0, 12.0] 11.0
13 [11.0, 12.0, 13.0] 12.0
14 [12.0, 13.0, 14.0] 13.0
15 [13.0, 14.0, 15.0] 14.0
16 [14.0, 15.0, 16.0] 15.0
17 [15.0, 16.0, 17.0] 16.0
18 [16.0, 17.0, 18.0] 17.0
19 [17.0, 18.0, 19.0] 18.0

答案 8 :(得分:-1)

尝试限制列表的长度

_distance = []
if _distance.size == 3:
       _distance = _distance[-2:]
       _distance.append(distance)
else:
   _distance.append(distance)

 avg_distance = sum(distance[-3:]) / len(distance[-3:])