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



我正在使用公用事业仪表间隔数据,该数据由时间戳(通常以 1 小时或 15 分钟为增量)和能耗值(以千瓦或千瓦时为单位)组成。我想快速将具有单个读数的熊猫数据帧转换为包含每月、每小时平均值、最大值和计数的年度摘要。

年度摘要的格式将是 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

您可以使用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

我会使用分组然后取消堆栈:

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次乘以每个月的天数(有些月份比其他月份长)...

相关内容

最新更新