pandas 按半小时时间序列数据分组

pandas groupby half hourly timeseries data

我有一个半小时电力数据的时间序列,如下所示:

                Date_Time  Metered Electricity (MWh)
0     2016-03-27 00:00:00                   8.644511
1     2016-03-27 00:30:00                   6.808402
2     2016-03-27 01:00:00                   6.507068
3     2016-03-27 01:30:00                   5.271631
4     2016-03-27 02:00:00                   2.313497
...                   ...                        ...
58122 2019-06-30 11:30:00                   8.051935
58123 2019-06-30 12:00:00                   3.520226
58124 2019-06-30 12:30:00                   5.093964

我想将所有数据点平均为每半小时时间步长的平均值,最终我可以创建一个图表来显示全天平均发电量。

我已经设法使用 groupby 对每小时数据执行此操作,效果很好:

mean_hourly = energy_2018.groupby(energy_2018["Date_Time"].dt.hour).mean()

如果我无法弄清楚如何每半小时进行一次分组,我可以使用它,但这意味着我会丢失所有数据的一半。知道如何每半小时使用一次 groupby 以便我可以使用所有数据吗?

谢谢!

df = pd.read_excel('test.xlsx')
print(df)

输出:

            Date_Time  Metered Electricity (MWh)
0 2016-03-27 00:00:00                          1
1 2016-03-27 00:29:00                          2
2 2016-03-27 00:59:00                          3
3 2016-03-27 00:57:00                          4
4 2016-03-27 02:00:00                          5

然后这样做:

df.set_index('Date_Time',inplace=True)
df = df.resample("30T").mean().reset_index()
print(df)

输出:

            Date_Time  Metered Electricity (MWh)
0 2016-03-27 00:00:00                        1.5
1 2016-03-27 00:30:00                        3.5
2 2016-03-27 01:00:00                        NaN
3 2016-03-27 01:30:00                        NaN
4 2016-03-27 02:00:00                        5.0

编辑

或仅此:

df = df.set_index('Date_Time').resample("30T").mean().reset_index()

您可以按小时和分钟进行分组和分组。由于您仅以半小时为间隔记录数据,因此您每小时和每 30 分钟得到一个不同的组。

import pandas as pd
df = pd.DataFrame({
    'time': ['2016-03-27 00:00:00',
            '2016-03-27 00:00:00',                  
            '2016-03-27 00:30:00',                  
            '2016-03-27 01:00:00',                   
            '2016-03-27 01:30:00',                 
            '2019-06-30 11:30:00',                   
            '2019-06-30 12:00:00',                 
            '2019-06-30 12:30:00'],
    'electricity': [8.644511,
                    6.808402,
                    6.507068,
                    5.271631,
                    2.313497,
                    8.051935,
                    3.520226,
                    5.093964]
})

df['time'] = pd.to_datetime(df['time'])
df['minutes'] = df['time'].apply(lambda x: x.minute)
df['hour'] = df['time'].apply(lambda x: x.hour)
df.groupby(['hour', 'minutes']).mean()

输出:

编辑:

如 Quang Hoang 的评论所述,获取小时和分钟的更好方法是

df['minutes'] = df['time'].dt.minute
df['hour'] = df['time'].dt.hour

最好使用标准库中的现有解决方案,以提高可读性和性能。另一方面 lambda expressions 确实提供了一些灵活性并且有时非常有用。如果您有兴趣,可以在这里阅读更多内容:

Why are Python lambdas useful?

https://www.code-learner.com/advantages-and-disadvantages-of-lambda-expressions-in-python-and-their-usage-scenarios/

energy_2018.groupby(energy_2018["Date_Time"].astype('int64') / 1e9 % 86400 / 3600).mean()

要为 'grouped aggregated time' 中的所有行生成相同的聚合值,请结合使用 pd.groupby 和 pd.Grouper。 return 聚合值到每一行而不是重塑数据帧的技巧是之后使用转换函数(我使用了 numpy 的平均值(np.mean)所以一定要在代码中将 numpy 导入为 np) .如果您需要更具体的灵活性(例如每 10 分钟一次,但第一分钟从某个偏移分钟而不是零开始(例如 00:02:00 而不是 00:00:00),则需要其他参数。

import numpy as np

energy_2018["mean_hourly"] = energy_2018.groupby(pd.Grouper(key="Date_Time", freq="60Min")).transform(np.mean)

Date_Time               Metered Electricity (MWh)  mean_hourly
2016-03-27 00:03:00                   8.644511     7.726456
2016-03-27 00:31:00                   6.808402     7.726456
2016-03-27 01:00:00                   6.507068     5.889349
2016-03-27 01:30:00                   5.271631     5.889349
2016-03-27 02:00:00                   2.313497     2.313497