首页 > 解决方案 > 对列进行分组以形成时间序列数据(Python)

问题描述

我有一个看起来像这样的数据框 df

餐厅 开放时间 关闭时间 团体
ABX 10:00:00 21:00:00 金子
BWZ 13:00:00 14:00:00
GTW 10:00:00 11:00:00 金子

我想根据我选择的开始和结束日期创建一个时间序列数据框 df2,它显示按组开放并按所有时间索引的餐厅。在这种情况下,我选择了 2021 年 5 月 17 日的开始日期和 2021 年 5 月 18 日的结束日期。最终的数据框应如下所示

日期 金子
2021-05-17 9:00:00 0 0
2021-05-17 10:00:00 2 0
2021-05-17 11:00:00 1 0
2021-05-17 12:00:00 1 0
2021-05-17 13:00:00 1 1
2021-05-17 14:00:00 1 1
2021-05-17 15:00:00 1 0
…………………………………………………………………………………………………………………… …… ...........
…………………………………………………………………………………………………………………… …… ...........
2021-05-18 23:00:00 0 0

如果 Date 部分太难重新创建,那么时间也会有帮助,看起来像这样

时间 金子
9:00:00 0 0
10:00:00 2 0
11:00:00 1 0
12:00:00 1 0
13:00:00 1 1
14:00:00 1 1
15:00:00 1 0
…………………………………………………………………………………………………………………… …… ...........
…………………………………………………………………………………………………………………… …… ...........
23:00:00 0 0

任何帮助将不胜感激。

标签: pandasdatedatetimetime-seriespandas-groupby

解决方案


第一部分:时间

创建一个包含所有时间的列表,opentime然后closetime将列表分解为行并分组,(time, group)并计算每个组的值。

第二部分:日期

创建一个包含start_date和之间的所有小时的日期时间索引end_date。转换为一个系列,并将时间设置为索引。

上一部分:合并日期和时间

dfd将(日期数据框)和(时间数据框)合并dft在一起以获取每个日期时间的组。

start_date = "2021-05-17"
end_date = "2021-05-18"

# compute hours between opentime and closetime
df["time"] = df.apply(lambda x: pd.date_range(x["opentime"],
                                              x["closetime"],
                                              freq="1H").time, axis="columns")

# value count by time and group
dft = df.explode("time").value_counts(["time", "group"]).unstack("group")

# create datetime index between start_date and end_date
dti = pd.date_range(start=pd.to_datetime(start_date),
                    end=pd.to_datetime(end_date) + pd.DateOffset(days=1),
                    closed="left", freq="1H", name="datetime")
dfd = dti.to_series(index=dti.time)

# merge date and time dataframes
out = pd.merge(dfd, dft, left_index=True, right_index=True, how="left") \
        .set_index("datetime").sort_index().fillna(0)
>>> out
                     Gold  Silver
datetime
2021-05-17 00:00:00   0.0     0.0
2021-05-17 01:00:00   0.0     0.0
2021-05-17 02:00:00   0.0     0.0
2021-05-17 03:00:00   0.0     0.0
2021-05-17 04:00:00   0.0     0.0
2021-05-17 05:00:00   0.0     0.0
2021-05-17 06:00:00   0.0     0.0
2021-05-17 07:00:00   0.0     0.0
2021-05-17 08:00:00   0.0     0.0
2021-05-17 09:00:00   0.0     0.0
2021-05-17 10:00:00   2.0     0.0
2021-05-17 11:00:00   2.0     0.0
2021-05-17 12:00:00   1.0     0.0
2021-05-17 13:00:00   1.0     1.0
2021-05-17 14:00:00   1.0     1.0
2021-05-17 15:00:00   1.0     0.0
2021-05-17 16:00:00   1.0     0.0
2021-05-17 17:00:00   1.0     0.0
2021-05-17 18:00:00   1.0     0.0
2021-05-17 19:00:00   1.0     0.0
2021-05-17 20:00:00   1.0     0.0
2021-05-17 21:00:00   1.0     0.0
2021-05-17 22:00:00   0.0     0.0
2021-05-17 23:00:00   0.0     0.0
2021-05-18 00:00:00   0.0     0.0
2021-05-18 01:00:00   0.0     0.0
2021-05-18 02:00:00   0.0     0.0
2021-05-18 03:00:00   0.0     0.0
2021-05-18 04:00:00   0.0     0.0
2021-05-18 05:00:00   0.0     0.0
2021-05-18 06:00:00   0.0     0.0
2021-05-18 07:00:00   0.0     0.0
2021-05-18 08:00:00   0.0     0.0
2021-05-18 09:00:00   0.0     0.0
2021-05-18 10:00:00   2.0     0.0
2021-05-18 11:00:00   2.0     0.0
2021-05-18 12:00:00   1.0     0.0
2021-05-18 13:00:00   1.0     1.0
2021-05-18 14:00:00   1.0     1.0
2021-05-18 15:00:00   1.0     0.0
2021-05-18 16:00:00   1.0     0.0
2021-05-18 17:00:00   1.0     0.0
2021-05-18 18:00:00   1.0     0.0
2021-05-18 19:00:00   1.0     0.0
2021-05-18 20:00:00   1.0     0.0
2021-05-18 21:00:00   1.0     0.0
2021-05-18 22:00:00   0.0     0.0
>>> dfd.index
Index([00:00:00, 01:00:00, 02:00:00, 03:00:00, 04:00:00, 05:00:00, 06:00:00,
       07:00:00, 08:00:00, 09:00:00, 10:00:00, 11:00:00, 12:00:00, 13:00:00,
       14:00:00, 15:00:00, 16:00:00, 17:00:00, 18:00:00, 19:00:00, 20:00:00,
       21:00:00, 22:00:00, 23:00:00, 00:00:00, 01:00:00, 02:00:00, 03:00:00,
       04:00:00, 05:00:00, 06:00:00, 07:00:00, 08:00:00, 09:00:00, 10:00:00,
       11:00:00, 12:00:00, 13:00:00, 14:00:00, 15:00:00, 16:00:00, 17:00:00,
       18:00:00, 19:00:00, 20:00:00, 21:00:00, 22:00:00, 23:00:00],
      dtype='object')

>>> dft.index
Index([10:00:00, 11:00:00, 12:00:00, 13:00:00, 14:00:00, 15:00:00, 16:00:00,
       17:00:00, 18:00:00, 19:00:00, 20:00:00, 21:00:00],
      dtype='object', name='time')

推荐阅读