首页 > 解决方案 > Python 上的每日数据到每月平均值

问题描述

我真的(真的)是 Python 语言的新手,我在使用每日数据计算河流流量的月平均值时遇到了一些问题。数据示例:

01/01/1981/;42.989
02/01/1981/;32.093
03/01/1981/;25.334
04/01/1981/;25.334
05/01/1981/;25.767
06/01/1981/;28.868
07/01/1981/;40.925
08/01/1981/;29.777
...
04/02/1981/;27.969
05/02/1981/;27.969
06/02/1981/;29.777
07/02/1981/;30.696
...
29/12/2014/;91.843
30/12/2014/;83.645
31/12/2014/;77.336

我会使用每日数据计算每月河流流量。我也知道像 numpy 或 panda 这样的包可以做到这一点,但我需要在不使用它们的情况下做到这一点。

for row in arq:
    a = row.split(';')
    x = a[0]
    y = float(a[1])
    x = row.split("/" or "/;  ")
    day = int(x[0])
    month = int(x[1])
    year = int(x[2])
    nl.append(y)
    average = sum(nl)/ len(nl)
print(average)

因此,如果您能提供帮助,我将不胜感激。

标签: pythonaverage

解决方案


此解决方案使用字典monthly_averages来跟踪每个年/月组合的运行平均值。它将数据存储在一个元组对中,第一个值是当前平均值,第二个值是观察次数(需要更新任何后续数据的平均值)。

请注意,avg observations = sum(observations) / n其中n是观察次数。给定一个新的数据点,新的平均值将为(sum(observations) + new data point) / (n + 1). 然后将其表示为(sum(observations) / n * n / (n + 1) + new data point) / (n + 1)。请注意,这sum(observations) / n是我们之前的平均值,因此新的平均值可以表示如下 new_avg = prior_avg * n / (n + 1) + new data point / (n + 1):或者,更简单地说:new_avg = (prior_avg * n + new data point) / (n + 1).

我相信其余的代码是不言自明的,但是如果您不理解其中任何一个,请告诉我,然后我会尽力澄清。

monthly_averages = {}
for row in arq:
    date, daily_rainfall = row.split(';')  # Tuple unpacking.
    day, month, year = date[:-1].split('/')  # Still string format, but that is ok.
    prior_data = monthly_averages.get((year, month))
    if prior_data:
        prior_avg, count = prior_data   # Tuple unpacking.
        new_avg = (prior_avg * count + float(daily_rainfall)) / (count + 1) 
        monthly_averages[(year, month)] = (new_avg, count + 1)
    else:
        monthly_averages[(year, month)] = (float(daily_rainfall), 1)

按排序顺序打印结果:

for year_month in sorted(monthly_averages):
    print('{}-{}: {:.2f}'.format(*year_month, monthly_averages[year_month][0]))

推荐阅读