You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas DataFrame多列连续分组计数问题求助

解决Pandas多列连续分组统计次数的问题

嘿,这个场景我做日志行为统计的时候常碰到,其实把单列连续分组的逻辑扩展到多列特别简单,核心就是同时判断多列是否和上一行完全一致,给连续的相同组合打上唯一标识,再分组统计就行。

我给你一步步拆解实现过程:

1. 构造示例数据

先把你提供的示例数据用Pandas创建出来:

import pandas as pd

data = {
    'Time': [1, 2, 3, 4, 5],
    'Object': ['A', 'A', 'A', 'B', 'B'],
    'Status': ['On', 'Off', 'On', 'On', 'On']
}
df = pd.DataFrame(data)

2. 创建连续分组的唯一标识

单列时我们用df['col'] != df['col'].shift()判断分组切换,多列要同时检查Object和Status——只要其中一列和上一行不同,就算是新的连续组。用ne()(不等于)+any(axis=1)(任意一列满足)生成切换标记,再用cumsum()累加得到每个连续组的ID:

# 生成分组ID:每遇到Object或Status变化,ID就+1
df['group_id'] = df[['Object', 'Status']].ne(df[['Object', 'Status']].shift()).any(axis=1).cumsum()

这一步后,你的DataFrame会变成这样:

TimeObjectStatusgroup_id
1AOn1
2AOff2
3AOn3
4BOn4
5BOn4

3. 分组统计连续次数

现在按Object、Status和group_id分组,统计每个组的行数(也就是连续持续的次数),最后去掉group_id列就得到你想要的结果:

# 分组统计并重命名列
result = df.groupby(['Object', 'Status', 'group_id'], as_index=False).size().rename(columns={'size': 'Duration'})
# 移除临时的group_id列
result = result.drop('group_id', axis=1)

最终结果

运行完上面的代码,result就是你期望的输出:

Object Status  Duration
0      A     On         1
1      A    Off         1
2      A     On         1
3      B     On         2

简化版代码(可选)

如果不想生成临时的group_id列,也可以把分组逻辑直接写到groupby里,一步到位:

result = (
    df.groupby([
        df['Object'].ne(df['Object'].shift()).cumsum(),
        df['Status'].ne(df['Status'].shift()).cumsum()
    ])
    .agg(Object=('Object', 'first'), Status=('Status', 'first'), Duration=('Time', 'count'))
    .reset_index(drop=True)
)

这个写法更简洁,原理和前面一致,只是把分组标识的生成内嵌到了groupby参数里。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:16:48