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

Calculate 20 minute average & best 20 minute average

我正在尝试学习 Python,我正在通过一个项目从自行车功率计读取数据。现在我只是计算从开始到结束的平均功率,方法是将每个功率读数加到总和变量中,然后除以读数的数量。

我想计算 20 分钟的平均功率,如果可能的话,在前 20 分钟后每 30 秒继续计算 20 分钟的平均值,与之前的值进行比较,如果高于最后,所以最终我可以获得比我在一小时锻炼期间保持的更高的 20 分钟平均功率,例如,无论它在那个小时内发生在哪里。

功率计的数据是基于事件的,据我所知这不是固定的时间间隔,但绝对是每秒一次或更快。 到目前为止,这是我的代码的基础:

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))

不太确定如何解决这个问题!非常感谢任何帮助或指示!

您可以使用 pandas 数据框来存储每个实例的功率输出。

考虑到您每 30 秒收到一个值,您可以将它们全部存储在数据框中。

然后使用 python 中的滚动函数计算 40 个数据点的移动平均值。

取滚动函数后得到的最大值,这就是你的最终结果。

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

如果你是实时读取数据,我假设你是在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)

在这里,我在控制台中输入一个数字,然后按回车键来模拟您的自行车功率计。

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

现在,如果你想做一个移动平均,你必须存储你想要平均的读数。这是因为您想稍后删除它们,因为它们太旧了。 list 非常适合:

这是对最后 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))

给出:

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

请注意,列表在删除开头附近的元素时效率不高,因此有更有效的方法(循环缓冲区),但我尽量保持简单 ;)

您可以通过猜测您有多少 readings/seconds 并选择 n 来使用它,这样您平均超过 20 分钟。
如果你想真正平均所有不到 20 分钟前的结果,你不仅需要记录读数,还需要记录你红色的时间,这样你就可以删除超过 20 分钟的旧读数。如果这是您需要的,请告诉我,我将通过示例扩展我的答案。