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会变成这样:
| Time | Object | Status | group_id |
|---|---|---|---|
| 1 | A | On | 1 |
| 2 | A | Off | 2 |
| 3 | A | On | 3 |
| 4 | B | On | 4 |
| 5 | B | On | 4 |
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
相关产品推荐
相关产品推荐

