简体   繁体   English

计算 20 分钟平均值和最佳 20 分钟平均值

[英]Calculate 20 minute average & best 20 minute average

I'm trying to learn Python, with a project where I'm reading data from a bike power meter.我正在尝试学习 Python,有一个项目,我正在从自行车功率计读取数据。 Right now I'm just calculating the average power from start to finish, by adding each power reading to a total sum variable, and dividing it with the number of readings.现在我只是计算从开始到结束的平均功率,将每个功率读数添加到总和变量中,然后除以读数数量。

I'd like to calculate the average power for 20 minutes, and if possible, keep calculating the 20 minute average each 30 seconds after the first 20 minutes, comparing to the previous value and storing it if it's higher than the last, so in the end I could have the higher 20 minute average power that I held during a one hour workout, no matter where it happened in that hour, for example.我想计算 20 分钟的平均功率,如果可能,在前 20 分钟后每 30 秒继续计算 20 分钟的平均值,与前一个值进行比较,如果它高于上一个值,则将其存储,因此在例如,无论那一小时发生在何处,我都可以拥有比一小时锻炼期间更高的 20 分钟平均功率。

Data from the power meter is event based, as far as I can tell it's not a regular intervals, but definitely once a second or faster.来自功率计的数据是基于事件的,据我所知,它不是定期的,但绝对是每秒一次或更快。 This is the base of my code so far:到目前为止,这是我代码的基础:

def average_power(power, count):
    global PM1_sumwatt
    global PM1_avgwatt
    PM1_sumwatt = PM1_sumwatt + power
    PM1_avgwatt = PM1_sumwatt / count
    PM1_avgLog = open(PM1_avgFile, 'w')
    PM1_avgLog.write("<div id=\"pwr\"> %d W</div>" % (PM1_avgwatt))
    PM1_avgLog.close()

def power_data(eventCount, pedalDiff, pedalPowerRatio, cadence, accumPower, instantPower):
     global PM1_avgcount
     if WCORRECT1: calibpower = instantPower+(CF1w)
     else: calibpower = instantPower*(CF1x)
     power_meter.update(int(calibpower))
     PM1_avgcount = PM1_avgcount + 1
     average_power(int(calibpower), PM1_avgcount)


power  = BicyclePower(readnode, network, callbacks = {'onDevicePaired': device_found,
                                              'onPowerData': power_data})


# Starting PM readings
power.open(ChannelID(PM1, 11, 0))

Not quite sure how to tackle this!不太确定如何解决这个问题! Any help or pointer is much appreciated!非常感谢任何帮助或指针!

You can use pandas dataframe to store the power output for each instance.您可以使用 pandas 数据帧来存储每个实例的功率输出。

Considering that you receive a value each 30 second, you can store them all in data frame.考虑到您每 30 秒收到一个值,您可以将它们全部存储在数据框中。

Then calculate a 40 data point moving average using rolling function in python.然后使用python中的滚动函数计算40个数据点的移动平均值。

Take the max value you get after the rolling function, this would be your final result.取滚动函数后获得的最大值,这将是您的最终结果。

refer this for doc : https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rolling.html参考这个文档: https : //pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rolling.html

if you are reading data in real time, I assume you are reading the data in a while loop:如果您正在实时读取数据,我假设您是在 while 循环中读取数据:

sum = 0
number_of_readings = 0
while True:  # forever
    new_value = input()  # here I read from the console input
    sum += new_value
    number_of_readings += 1
    average = sum/number_of_readings 
    print(average)

Here I type a number in the console and press enter to simulate your bike power meter.在这里,我在控制台中输入一个数字,然后按 Enter 来模拟您的自行车功率计。

>>> 1
1.0
>>> 3
2.0
>>> 4
2.6666666666666665
>>> 2
2.5

Now, if you wants to make a moving average, you must store the readings that you wants to average.现在,如果您想制作移动平均线,您必须存储您想要平均的读数。 This is because you want to remove them later, when they will be too old.这是因为您想稍后删除它们,因为它们太旧了。 A list is perfect for that:一个列表非常适合:

Here is a solution averaging the last n readings:这是对最后n读数求平均值的解决方案:

n = 2
Last_n_readings = []
while True:  # forever
    # add a new reading
    new_value = int(input())  # here I read from the console input
    Last_n_readings.append(new_value)
    # discard an old one (except when we do not have enough readings yet)
    if len(Last_n_readings) > n:
        Last_n_readings.pop(0)
    # print the average of all the readings still in the list
    print(sum(Last_n_readings) / len(Last_n_readings))

Which gives:这使:

>>> 1
1.0
>>> 3
2.0
>>> 4
3.5
>>> 2
3.0

Note that lists are not very efficient when removing elements near the start, so there are more effective ways to do this (circular buffers), but I try to keep it simple ;)请注意,列表在删除开头附近的元素时效率不是很高,因此有更有效的方法来执行此操作(循环缓冲区),但我尽量保持简单;)

You could use this by guessing how many readings/seconds you have and choose n so you average over 20 minutes.您可以通过猜测您有多少读数/秒并选择n来使用它,以便您平均超过 20 分钟。
If you want to truly average all the result which are less than 20 minutes ago, you need to not only record the readings but also the times when you red them, so you can remove the old readings wen they get more than 20 minutes old.如果你想真正平均所有不到20分钟前的结果,你不仅需要记录读数,还需要记录你红色的次数,这样你就可以删除20分钟前的旧读数。 If this is what you need, tell me and I will expand my answer with an example.如果这是您需要的,请告诉我,我将用一个例子来扩展我的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM