每小时时间序列上列的平均值

Posted

技术标签:

【中文标题】每小时时间序列上列的平均值【英文标题】:Average values from a column on an hourly timeseries 【发布时间】:2015-04-30 04:39:39 【问题描述】:

我有一个很长的列表(10 年)每小时值,我想平均第 3 列,每天。这样每个日期都将具有从第 3 列得出的平均值。

我的数据如下所示:

>     1/1/2005,16:00:00,83.3971,-3.8950
>     1/1/2005,17:00:00,0.0000,-3.9146
>     1/1/2005,18:00:00,0.0000,-3.9337
>     1/1/2005,19:00:00,0.0000,-3.9532
>     1/1/2005,20:00:00,0.0000,-3.9727
>     1/1/2005,21:00:00,0.0000,-3.9920
>     1/1/2005,22:00:00,0.0000,-4.0116
>     1/1/2005,23:00:00,0.0000,-4.0311
>     1/2/2005,0:00:00,0.0000,-4.0503
>     1/2/2005,1:00:00,0.0000,-4.0697
>     1/2/2005,2:00:00,0.0000,-4.0891
>     1/2/2005,3:00:00,0.0000,-4.1083
>     1/2/2005,4:00:00,0.0000,-4.1279
>     1/2/2005,5:00:00,0.0000,-4.1472
>     1/2/2005,6:00:00,0.0000,-4.1662
>     1/2/2005,7:00:00,0.0000,-4.1858
>     1/2/2005,8:00:00,0.0000,-4.2053
>     1/2/2005,9:00:00,152.7058,-4.2242
>     1/2/2005,10:00:00,302.6400,-4.2436
>     1/2/2005,11:00:00,405.2218,-4.2630
>     1/2/2005,12:00:00,452.6208,-4.2821
>     1/2/2005,13:00:00,441.4662,-4.3016
>     1/2/2005,14:00:00,372.5459,-4.3208
>     1/2/2005,15:00:00,250.8291,-4.3398
>     1/2/2005,16:00:00,86.6172,-4.3592
>     1/2/2005,17:00:00,0.0000,-4.3785
>     1/2/2005,18:00:00,0.0000,-4.3973
>     1/2/2005,19:00:00,0.0000,-4.4167
>...
12/30/2014,23:00:00,0.0000,0.7601
12/31/2014,0:00:00,0.0000,0.7601
12/31/2014,1:00:00,0.0000,0.7601
12/31/2014,2:00:00,0.0000,0.7601
12/31/2014,3:00:00,0.0000,0.7601
12/31/2014,4:00:00,0.0000,0.7601
12/31/2014,5:00:00,0.0000,0.7601
12/31/2014,6:00:00,0.0000,0.7601
12/31/2014,7:00:00,0.0000,0.7601
12/31/2014,8:00:00,0.0000,2.6808
12/31/2014,9:00:00,153.8084,1.6338
12/31/2014,10:00:00,301.9711,1.3491
12/31/2014,11:00:00,402.5888,1.2512
12/31/2014,12:00:00,447.9860,1.2191
12/31/2014,13:00:00,434.9283,1.2277

...

这可能是一个很好的机会来突出 "Split, Apply, Combine" 前提和一个简单的案例使用?

也许读取 csv 到 pandas,索引为日期时间对象,然后 groupby day,聚合总和/除以计数(又名 平均)?

问题: 我需要平均每日价值,我从上述 10 年每小时时间序列开始。例如,我有一个从 2005 年 1 月 1 日到 2014 年 12 月 31 日的每小时数据集,我想要基于该数据集的 10 年每日平均值的每日平均值。你挖?

我已经从每小时到每天使用:

df = pd.read_csv('file.csv', parse_dates='datetime':0,1],index_col='datetime', header=True, usecols=[0,1,2])

day_avgs = df.groupby(pd.TimeGrouper('D'))

这确实会返回平均每日值,见下文:

date  

2005-01-01  106.307291
2005-01-02  102.578729
2005-01-03  103.332883
2005-01-04  104.139979
2005-01-05  104.999592
... ...
2014-12-02  108.292092
2014-12-03  107.189729
2014-12-04  106.142721
2014-12-05  105.151696

但是,我不知道如何将这些每日值分组到“day_avgs”中,因此在每个日期(其中 10 个)分组,然后平均给出一个每日平均值,即所有这些日期的平均值超过 10 年的数据集。卡皮奇?

即,我想根据 10 年的每日平均值计算一年中每天的平均值 (365)。

【问题讨论】:

为什么要除以 8?你有额外的 8 个观察值,你想打折 0.0000 值 另外你的问题有很多问题,这是不鼓励这样做的,理想情况下每个帖子1个问题,所以你需要编辑你的问题 我的问题只有一个,但有步骤,毫无疑问。我可以处理包括当天的平均值在内的平均值,或者不处理任何对受访者来说最容易的平均值。 -8 只是平均计算的一个例子。我认为这个问题(同样,只有 1 个)值得不编辑,因为我相信答案将大大有助于帮助他人。谢谢 【参考方案1】:

求一年中每一天的平均值

#!/usr/bin/env python
from datetime import datetime
import pandas

def same_day(date_string): # remove year
    return datetime.strptime(date_string, "%m/%d/%Y").strftime('%m-%d')

df = pandas.read_csv('input.csv', index_col=0,
                     usecols=[0,2], names=['date', 'value'],
                     converters='date': same_day)
print(df.groupby(level=0).mean())

输出

            value
date             
01-01  143.991035
01-02  123.232340
12-30    0.000000
12-31  100.981233

假设所有小时值在不同年份具有相同的权重。

求每个日期的平均值

pandas 允许索引中的重复值。

按日期(第 1 列)对数据进行分组并求第 3 列的平均值:

#!/usr/bin/env python
import pandas

df = pandas.read_csv('input.csv', parse_dates=True, index_col=0,
                     usecols=[0,2], names=['date', 'value'])
print(df.groupby(level=0).mean())

输出

                 value
date                  
2005-01-01  143.991035
2005-01-02  123.232340

[2 rows x 1 columns]

使用itertools.groupby() 的代码产生相同的结果:

#!/usr/bin/env python
import csv
from collections import OrderedDict
from datetime import datetime
from itertools import groupby
from operator import itemgetter
from pprint import pprint

def groupby_mean(file):
    mean = OrderedDict()
    for day, same_day_rows in groupby(csv.reader(file), key=itemgetter(0)):
        L = [float(row[2]) for row in same_day_rows]
        mean[datetime.strptime(day, '%m/%d/%Y')] = sum(L) / len(L)
    return mean

with open('input.csv') as file:
    pprint(groupby_mean(file))

输出

datetime.datetime(2005, 1, 1, 0, 0): 143.99103529411764,
 datetime.datetime(2005, 1, 2, 0, 0): 123.23234

math.fsum(L) 与您输入的sum(L) 产生相同的结果。

【讨论】:

关闭,但不完全,但这是我的错,因为我解释得不够清楚。我的问题已更新。 @geokrowding:让我们简化一下。我的代码使用您问题中的数据。它产生两行。您希望该数据得到什么结果? 我认为问题很明确。数据是 10 年的,不是一年。抱歉,您的方法没有提供答案。此外,level=0 没有使用我的数据,所以不确定它是如何为你工作的。我在上面编辑的代码中完成了同样的事情。感谢您的尝试,请随时将其更进一步,简单地平均所有平均天数......这就是问题,很简单。 @geokrowding:您的输入数据仅持续两天。你已经改变了问题。所有代码都经过测试。它适用于 Python 2 和 3。pandas.__version__0.13.1 我没有更改问题,但我确实更好地限定了它。我认为在这篇文章中包含 10 年的每小时价值是不可取的。我最好通过实际说明其长度 - 10 年并在其末尾添加“......”来限定我的“非常长列表”的陈述。我希望这能消除任何误解。如果还不清楚,请参考后面的数据样本,包括数据集的头部和尾部。

以上是关于每小时时间序列上列的平均值的主要内容,如果未能解决你的问题,请参考以下文章

计算由时间间隔分隔的连续每小时记录块的平均值

如何获取具有多列的时间序列数据框中的每小时平均值

从 netcdf 文件中获取每个月的每小时平均值

mysql查询每小时平均值

Pandas 将 5 分钟数据重新采样为每小时平均值:日期问题 [重复]

Pandas GroupBy 和 MultiIndex 上列级别的最大值