我正在使用距离传感器在树莓派上开发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个)距离的平均值
重要 : 我不想存储所有值,因为此脚本将运行几天又几天
答案 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:])