You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Pandas透视表中使用分组函数及按固定时间段分组

嘿,我来帮你搞定这两个Pandas的问题,都是实际数据分析里很常用的场景哦!

1. 如何在Pandas透视表中使用分组函数?

Pandas的pivot_table本身就支持通过aggfunc参数指定分组聚合逻辑,不管是内置函数还是自定义函数都能搞定,甚至还能结合groupby先做更细的分组再生成透视表。给你几个实用的例子:

先准备示例数据

import pandas as pd
import numpy as np

# 构造测试数据
df = pd.DataFrame({
    'Category': ['A', 'A', 'B', 'B', 'A', 'B'],
    'Subcategory': ['X', 'Y', 'X', 'Y', 'X', 'Y'],
    'Value': [10, 20, 15, 25, 30, 35]
})

用内置聚合函数做透视表

最基础的用法,直接给aggfunc传内置的统计函数,比如求和、均值,甚至可以传一个列表同时用多个函数:

# 同时计算求和和均值的透视表
pivot_basic = pd.pivot_table(df, 
                             index='Category', 
                             columns='Subcategory', 
                             values='Value', 
                             aggfunc=[np.sum, np.mean])
print(pivot_basic)

自定义分组聚合函数

如果内置函数满足不了需求,比如想计算每组的极差(最大值减最小值),可以自己写个函数传给aggfunc

# 自定义聚合函数:计算数值范围
def calculate_range(x):
    return x.max() - x.min()

# 应用自定义函数的透视表
pivot_custom = pd.pivot_table(df, 
                              index='Category', 
                              columns='Subcategory', 
                              values='Value', 
                              aggfunc=calculate_range)
print(pivot_custom)

先分组再做透视表

如果需要先按某个维度分组,再对每个子组单独生成透视表,可以结合groupbyapply

# 先按Category分组,每个组内生成透视表
grouped_pivot = df.groupby('Category').apply(
    lambda group: pd.pivot_table(group, index='Subcategory', values='Value', aggfunc=np.sum)
)
print(grouped_pivot)
2. 按固定1小时时间段分组时间字段作为透视表索引

你的场景是把hh:mm:ss.ms格式的时间按12:30-13:30、13:30-14:30这类固定区间分组,核心是先把时间转成datetime类型,再用区间切割来生成分组标签,最后用这个标签做透视表索引。

步骤拆解+代码示例

import pandas as pd

# 构造你的示例数据
df_time = pd.DataFrame({
    'ActualTime': ['12:30', '12:31', '12:46', '13:05', '13:22', '13:48', '14:05'],
    'Value': [5, 8, 3, 10, 7, 12, 6]
})

# 第一步:把时间字符串转成datetime类型(如果有毫秒,格式改成'%H:%M:%S.%f')
df_time['ActualTime'] = pd.to_datetime(df_time['ActualTime'], format='%H:%M')

# 第二步:生成自定义时间区间
start_time = pd.to_datetime('12:30', format='%H:%M')  # 起始区间点
interval_hours = 1  # 每个区间1小时

# 用pd.cut切割时间,生成区间分组
df_time['TimeInterval'] = pd.cut(
    df_time['ActualTime'],
    bins=pd.date_range(start=start_time, 
                       end=df_time['ActualTime'].max() + pd.Timedelta(hours=interval_hours),
                       freq=f"{interval_hours}H"),
    right=False,  # 左闭右开:比如12:30<=时间<13:30归为第一个区间
    include_lowest=True  # 确保第一个时间点12:30被包含进去
)

# 第三步:把区间标签格式化成你要的"hh:mm-hh:mm"样式
df_time['TimeInterval'] = df_time['TimeInterval'].apply(
    lambda x: f"{x.left.strftime('%H:%M')}-{x.right.strftime('%H:%M')}"
)

# 第四步:生成以时间段为索引的透视表(这里以求和为例,你可以换其他聚合函数)
time_pivot = pd.pivot_table(df_time, 
                            index='TimeInterval', 
                            values='Value', 
                            aggfunc=np.sum)
print(time_pivot)

运行后会得到这样的结果:

Value
TimeInterval        
12:30-13:30       33
13:30-14:30       18

如果你的时间字段包含毫秒,只需要把pd.to_datetimeformat参数改成'%H:%M:%S.%f'就行,其他逻辑完全通用。


内容的提问来源于stack exchange,提问作者Kartik

火山引擎 最新活动