如何利用Pandas groupby将DataFrame转换为按小时维度的时间表?
这问题我太熟啦!要把你的长格式DataFrame转成适合可视化的宽时间表,用Pandas的几个内置方法就能轻松搞定,下面给你具体代码和解释:
解决方案
我们可以用pivot_table(最省心的方式)或者groupby+unstack来实现需求,核心思路是把Hour列转成表头,用Floor的值填充对应位置,缺失的小时自动填0。
方法1:使用pivot_table(推荐)
这个方法能自动处理缺失值,还能灵活指定聚合规则,非常适合你的场景:
import pandas as pd # 先构造你的示例源数据 df = pd.DataFrame({ 'ID': ['Jay', 'Jay', 'Tim', 'Tim', 'Tim', 'Tom', 'Tom', 'Rob', 'Rob', 'Rob', 'Rob'], 'Hour': [2, 3, 0, 1, 2, 3, 4, 3, 4, 5, 6], 'Floor': [34, 34, 36, 34, 36, 32, 36, 31, 32, 33, 34] }) # 转换为宽表 result = df.pivot_table( index='ID', # 把ID作为行标识 columns='Hour', # 把Hour转成列 values='Floor', # 用Floor的值填充单元格 fill_value=0, # 缺失的小时填0 aggfunc='first' # 如果同一ID+Hour有多个值,取第一个(可按需换成max/min等) ).rename(columns=lambda x: f'HOUR_{x}').reset_index() # 把列名改成HOUR_xx格式,重置索引让ID变回普通列 print(result)
方法2:使用groupby配合unstack
如果你更习惯用groupby的思路,也可以这么写:
result = df.groupby(['ID', 'Hour'])['Floor'].first() \ .unstack(fill_value=0) \ .rename(columns=lambda x: f'HOUR_{x}') \ .reset_index()
输出结果
两种方法都会得到你期望的格式:
ID HOUR_0 HOUR_1 HOUR_2 HOUR_3 HOUR_4 HOUR_5 HOUR_6 0 Jay 0 0 34 34 0 0 0 1 Rob 0 0 0 31 32 33 34 2 Tim 36 34 36 0 0 0 0 3 Tom 0 0 0 32 36 0 0
补充说明
如果你的原始数据中,同一个ID+Hour组合存在多条记录,记得通过aggfunc参数指定聚合规则(比如'first'、'max'、'mean'),确保每个单元格只有一个值。
内容的提问来源于stack exchange,提问作者crackernutter
相关产品推荐
相关产品推荐

