代码之家  ›  专栏  ›  技术社区  ›  Sean Chon

将pandas间隔数据帧缩减为12个月x 24小时平均值的表

  •  0
  • Sean Chon  · 技术社区  · 7 年前

    我正在处理电表间隔数据,它由时间戳(通常为1小时或15分钟增量)和能耗值(以千瓦或千瓦时为单位)组成。我想 迅速地 将包含单个读数的pandas数据框架转换为包含平均值、最大值和每月每小时计数的年度摘要。

    年度摘要的格式将是12个月的X 24小时表(288个单元格),其中每个单元格是来自特定月份和小时的所有值的平均值、最大值或计数。

    为了简单起见,让我们看一下计数。 (从建议中,我可以推断出对平均值和最大值进行类似的计算)。

    我尝试了一种强力的方法,按月和小时过滤时间戳(一个288个值的循环),并将计数制成一个矩阵。然而,这种方法似乎非常缓慢,因为我执行这些计算在甚至20米。我很好奇是否有一个更快的方法来实现这一点,利用熊猫/numpy。

    下面是如何格式化间隔数据的示例。

    from datetime import datetime
    import pandas as pd
    
    df = pd.DataFrame()
    df["start"] = pd.date_range(start=datetime(2018, 1, 1), end=datetime(2018, 12, 31, 23), freq='900S')
    df["value"] = 1
    df.set_index("start", inplace=True)
    

    我目前正在按照以下思路进行计算:

    for month in range(1, 13):
        for hour in range(0, 24):
            count = df.query("index.dt.month == {} and index.dt.hour == {}".format(month, hour)).count()
    

    此数据的计数输出如下所示。(附带说明:有时数据不完整,此表有助于识别。)

         1    2    3    4    5    6    7    8    9    10   11   12
    0   124  112  124  120  124  120  124  124  120  124  120  124
    1   124  112  124  120  124  120  124  124  120  124  120  124
    2   124  112  124  120  124  120  124  124  120  124  120  124
    3   124  112  124  120  124  120  124  124  120  124  120  124
    4   124  112  124  120  124  120  124  124  120  124  120  124
    5   124  112  124  120  124  120  124  124  120  124  120  124
    6   124  112  124  120  124  120  124  124  120  124  120  124
    7   124  112  124  120  124  120  124  124  120  124  120  124
    8   124  112  124  120  124  120  124  124  120  124  120  124
    9   124  112  124  120  124  120  124  124  120  124  120  124
    10  124  112  124  120  124  120  124  124  120  124  120  124
    11  124  112  124  120  124  120  124  124  120  124  120  124
    12  124  112  124  120  124  120  124  124  120  124  120  124
    13  124  112  124  120  124  120  124  124  120  124  120  124
    14  124  112  124  120  124  120  124  124  120  124  120  124
    15  124  112  124  120  124  120  124  124  120  124  120  124
    16  124  112  124  120  124  120  124  124  120  124  120  124
    17  124  112  124  120  124  120  124  124  120  124  120  124
    18  124  112  124  120  124  120  124  124  120  124  120  124
    19  124  112  124  120  124  120  124  124  120  124  120  124
    20  124  112  124  120  124  120  124  124  120  124  120  124
    21  124  112  124  120  124  120  124  124  120  124  120  124
    22  124  112  124  120  124  120  124  124  120  124  120  124
    23  124  112  124  120  124  120  124  124  120  124  120  124
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   Chris Adams    7 年前

    你可以用 pandas.crosstab ,如果需要,则使用 DataFrame.rename_axis 根据所需输出移除轴名称。

    df_new = (pd.crosstab(df.index.hour, df.index.month)
              .rename_axis(None)
              .rename_axis(None, axis=1))
    

    [输出]

         1    2    3    4    5    6    7    8    9    10   11   12
    0   124  112  124  120  124  120  124  124  120  124  120  124
    1   124  112  124  120  124  120  124  124  120  124  120  124
    2   124  112  124  120  124  120  124  124  120  124  120  124
    3   124  112  124  120  124  120  124  124  120  124  120  124
    4   124  112  124  120  124  120  124  124  120  124  120  124
    5   124  112  124  120  124  120  124  124  120  124  120  124
    6   124  112  124  120  124  120  124  124  120  124  120  124
    7   124  112  124  120  124  120  124  124  120  124  120  124
    8   124  112  124  120  124  120  124  124  120  124  120  124
    9   124  112  124  120  124  120  124  124  120  124  120  124
    10  124  112  124  120  124  120  124  124  120  124  120  124
    11  124  112  124  120  124  120  124  124  120  124  120  124
    12  124  112  124  120  124  120  124  124  120  124  120  124
    13  124  112  124  120  124  120  124  124  120  124  120  124
    14  124  112  124  120  124  120  124  124  120  124  120  124
    15  124  112  124  120  124  120  124  124  120  124  120  124
    16  124  112  124  120  124  120  124  124  120  124  120  124
    17  124  112  124  120  124  120  124  124  120  124  120  124
    18  124  112  124  120  124  120  124  124  120  124  120  124
    19  124  112  124  120  124  120  124  124  120  124  120  124
    20  124  112  124  120  124  120  124  124  120  124  120  124
    21  124  112  124  120  124  120  124  124  120  124  120  124
    22  124  112  124  120  124  120  124  124  120  124  120  124
    23  124  112  124  120  124  120  124  124  120  124  120  124
    
        2
  •  1
  •   Andy Hayden    7 年前

    我会用一个groupby然后unstack:

    In [11]: res = df.groupby([df.index.month, df.index.hour])["value"].sum().unstack(0, fill_value=0)
    
    In [12]: res.columns.name = "month"  # or None to suppress
    
    In [13]: res.index.name = "hour"  # or None to suppress
    
    In [14]: res
    Out[44]:
    month   1    2    3    4    5    6    7    8    9    10   11   12
    hour
    0      124  112  124  120  124  120  124  124  120  124  120  124
    1      124  112  124  120  124  120  124  124  120  124  120  124
    2      124  112  124  120  124  120  124  124  120  124  120  124
    3      124  112  124  120  124  120  124  124  120  124  120  124
    4      124  112  124  120  124  120  124  124  120  124  120  124
    5      124  112  124  120  124  120  124  124  120  124  120  124
    6      124  112  124  120  124  120  124  124  120  124  120  124
    7      124  112  124  120  124  120  124  124  120  124  120  124
    8      124  112  124  120  124  120  124  124  120  124  120  124
    9      124  112  124  120  124  120  124  124  120  124  120  124
    10     124  112  124  120  124  120  124  124  120  124  120  124
    11     124  112  124  120  124  120  124  124  120  124  120  124
    12     124  112  124  120  124  120  124  124  120  124  120  124
    13     124  112  124  120  124  120  124  124  120  124  120  124
    14     124  112  124  120  124  120  124  124  120  124  120  124
    15     124  112  124  120  124  120  124  124  120  124  120  124
    16     124  112  124  120  124  120  124  124  120  124  120  124
    17     124  112  124  120  124  120  124  124  120  124  120  124
    18     124  112  124  120  124  120  124  124  120  124  120  124
    19     124  112  124  120  124  120  124  124  120  124  120  124
    20     124  112  124  120  124  120  124  124  120  124  120  124
    21     124  112  124  120  124  120  124  124  120  124  120  124
    22     124  112  124  120  124  120  124  124  120  124  120  124
    23     124  112  124  120  124  120  124  124  120  124  120  124
    

    注意:我得到不同的值,我得到大约120从4次每小时乘以每月的天数(有些月比其他月长)。