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

Python:按Person统计DataFrame中连续重复Activity A的分组信息

处理Pandas DataFrame:按用户统计连续Activity A的分组及平均时长

需求说明

给定包含Person、Activity、Time列的DataFrame,需完成两项任务:

  • 按Person统计连续重复次数超过2次的Activity A的分组数量
  • 计算这些符合条件分组的平均时长(每组结束时间减开始时间的总和除以分组数)

现有方案存在两个问题:无法按Person正确聚合,且处理700万行数据时性能不足,需要高效可行的解决方案。

原始数据示例

import pandas as pd

df = pd.DataFrame({
    "Person": ["P1", "P1","P1","P1","P1","P1","P1","P1","P1","P1", "P2", "P2","P2","P2","P2","P2","P2","P2","P2","P2"], 
    "Activity": ["A", "A", "A", "B", "A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "A", "A", "B", "A", "B", "A"],
    "Time": ["0", "0", "1", "1", "1", "3", "5", "5", "6", "6", "6", "6", "6", "6", "6", "6", "6", "6", "6", "6"]
})
# 先将Time转为数值类型,确保时长计算有效
df["Time"] = df["Time"].astype(int)

目标结果示例

solution = pd.DataFrame({
    "Person": ["P1", "P2"],
    "Activity": ["A", "A"],
    "Count": [2, 1], 
    "AVGTime": [3, 0]
})

高效解决方案

步骤1:标记连续相同Activity的分组

通过判断当前行与上一行的Person或Activity是否变化,生成连续分组的唯一标识:

df["group_id"] = (
    (df["Person"] != df["Person"].shift()) | 
    (df["Activity"] != df["Activity"].shift())
).cumsum()

步骤2:筛选符合条件的分组

按group_id聚合,提取每个分组的关键信息,再筛选出Activity为A且连续次数超过2次的分组:

group_stats = df.groupby("group_id").agg(
    Person=("Person", "first"),
    Activity=("Activity", "first"),
    count=("Activity", "size"),
    start_time=("Time", "min"),
    end_time=("Time", "max")
).query("Activity == 'A' and count > 2")

步骤3:按Person聚合计算最终结果

对筛选后的分组按Person和Activity聚合,统计分组数量并计算平均时长:

result = group_stats.groupby(["Person", "Activity"]).agg(
    Count=("group_id", "count"),
    total_duration=lambda x: (x["end_time"] - x["start_time"]).sum()
).assign(
    AVGTime=lambda x: x["total_duration"] / x["Count"]
).reset_index()

# 若需要保留所有Person(包括无符合条件分组的),可取消以下注释
# all_persons = df["Person"].unique()
# result = result.merge(
#     pd.DataFrame({"Person": all_persons, "Activity": "A"}),
#     on=["Person", "Activity"],
#     how="right"
# ).fillna(0)

# 调整列顺序匹配目标结果
result = result[["Person", "Activity", "Count", "AVGTime"]]

性能优化说明

  • 全程采用Pandas矢量化操作,避免逐行循环,处理700万行数据时效率远高于循环方案
  • 先筛选再聚合,大幅减少后续计算的数据量
  • groupby+agg组合基于底层C实现,是Pandas中最高效的聚合方式之一

验证结果

运行上述代码后,输出与目标结果一致:

print(result)
# 输出:
#   Person Activity  Count  AVGTime
# 0     P1        A      2      3.0
# 1     P2        A      1      0.0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 20:45:46