【问题标题】:Getting the average of a certain hour on weekdays over several years in a pandas dataframe在 pandas 数据框中获取几年内工作日某个小时的平均值
【发布时间】:2013-06-02 18:15:49
【问题描述】:

多年来,我有一个以下格式的每小时数据框:

Date/Time            Value
01.03.2010 00:00:00  60
01.03.2010 01:00:00  50
01.03.2010 02:00:00  52
01.03.2010 03:00:00  49
.
.
.
31.12.2013 23:00:00  77

我想对数据进行平均,以便获得每年 0 小时、1 小时... 23 小时的平均值。

所以输出应该看起来像这样:

Year Hour           Avg
2010 00              63
2010 01              55
2010 02              50
.
.
.
2013 22              71
2013 23              80

有人知道如何在 pandas 中获得这个吗?

【问题讨论】:

    标签: python datetime pandas average statistics


    【解决方案1】:

    注意:既然 Series 有 dt 访问器,那么日期作为索引就不太重要了,尽管 Date/Time 仍然需要是 datetime64。

    更新:您可以更直接地进行 groupby(不使用 lambda):

    In [21]: df.groupby([df["Date/Time"].dt.year, df["Date/Time"].dt.hour]).mean()
    Out[21]:
                         Value
    Date/Time Date/Time
    2010      0             60
              1             50
              2             52
              3             49
    
    In [22]: res = df.groupby([df["Date/Time"].dt.year, df["Date/Time"].dt.hour]).mean()
    
    In [23]: res.index.names = ["year", "hour"]
    
    In [24]: res
    Out[24]:
               Value
    year hour
    2010 0        60
         1        50
         2        52
         3        49
    

    如果是 datetime64 index 你可以这样做:

    In [31]: df1.groupby([df1.index.year, df1.index.hour]).mean()
    Out[31]:
            Value
    2010 0     60
         1     50
         2     52
         3     49
    

    旧答案(会更慢):

    假设日期/时间是索引*,您可以在 groupby 中使用映射函数:

    In [11]: year_hour_means = df1.groupby(lambda x: (x.year, x.hour)).mean()
    
    In [12]: year_hour_means
    Out[12]:
               Value
    (2010, 0)     60
    (2010, 1)     50
    (2010, 2)     52
    (2010, 3)     49
    

    对于更有用的索引,您可以从元组创建一个 MultiIndex:

    In [13]: year_hour_means.index = pd.MultiIndex.from_tuples(year_hour_means.index,
                                                               names=['year', 'hour'])
    
    In [14]: year_hour_means
    Out[14]:
               Value
    year hour
    2010 0        60
         1        50
         2        52
         3        49
    

    * 如果没有,那么先使用set_index:

    df1 = df.set_index('Date/Time')
    

    【讨论】:

    • 非常感谢。我一直在尝试使用循环,但这是一种更好的方法。
    • PS: 有谁可以填写“df1.groupby(lambda x: (x.year, x.hour)).mean( )" 作为动态参数进入 lamda 函数?为此“df1.groupby(lambda x: (Variable1, Variable2)).mean() ”定义 Varialbe1=x.year 和 Variable2=x.hour 似乎不起作用。
    • @MarkusW 您应该将其作为一个新问题提出:)...听起来您想使用适当的函数(即不是 lambda)
    • @AndyHayden 你是个天才。您能否澄清一下:lambda 函数是否总是默认使用索引?然后给定一个多索引,这默认为该多索引的元组?
    • @josh 是的,尽管您可以通过 as_index=False 来覆盖它。在重新阅读这个问题时,我会做一些不同的事情。更新了一种更好的方法来执行此操作(恰好直接创建多索引)。
    【解决方案2】:

    如果您的日期/时间列采用日期时间格式(请参阅 dateutil.parser 了解自动解析选项),您可以使用 pandas resample,如下所示:

    year_hour_means = df.resample('H',how = 'mean')
    

    这将使您的数据保持日期时间格式。这可能会帮助您处理您将要对数据进行的任何操作。

    【讨论】:

    • 这并不是从一天到下一天的平均值
    • @endolith 试试 daily_average = df.resample('D').mean() 其中 df 有 datetimeindex
    猜你喜欢
    • 2023-03-19
    • 2014-10-30
    • 2015-04-03
    • 1970-01-01
    • 2022-10-07
    • 2012-05-29
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多