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

如何在Pandas分组聚合中统计无事件的唯一用户数?

分组统计无事件唯一用户名的实现方案

原数据与初始代码

定义DataFrame

import pandas as pd

value = [["time1", "client1", None, "username1"], ["time2", "client1", "event1", "username1"], ["time3", "client1", None, "username2"], ["time4", "client2", None, "username3"], ["time5", "client2", "event2", "username4"], ["time6", "client3", None, "username5"]]
columns = ["timestamp", "clients", "events", "usernames"]
df = pd.DataFrame(value, columns=columns)

数据结构

timestamp  clients events  usernames
0     time1  client1   None  username1
1     time2  client1  event1  username1
2     time3  client1   None  username2
3     time4  client2   None  username3
4     time5  client2  event2  username4
5     time6  client3   None  username5

初始聚合代码

df.groupby("clients").agg(**{
    "total_records": ("timestamp", "size"),
    "unique_users": ("usernames", "nunique"),
    "without_events_records": ("events", lambda x: x.notnull().mean()),
    # "without_events_users":  add calculation without events per unique username
})

需求实现

根据业务场景的不同,提供两种without_events_users的统计方案:

场景1:统计至少有一条无事件记录的唯一用户名数量

只要用户在当前client分组中存在任意一条events为None的记录,就被计入统计。

修改后的聚合代码:

df.groupby("clients").agg(**{
    "total_records": ("timestamp", "size"),
    "unique_users": ("usernames", "nunique"),
    "without_events_records": ("events", lambda x: x.isnull().mean()),  # 修正原代码逻辑,统计无事件记录占比
    "without_events_users": ("usernames", lambda x: x[df.loc[x.index, "events"].isnull()].nunique())
})

运行结果:

total_records  unique_users  without_events_records  without_events_users
clients                                                                            
client1               3             2                0.666667                     2
client2               2             2                0.500000                     2
client3               1             1                1.000000                     1

场景2:统计所有记录均无事件的唯一用户名数量

仅当用户在当前client分组中的全部记录events都为None时,才被计入统计。

修改后的聚合代码:

df.groupby("clients").agg(**{
    "total_records": ("timestamp", "size"),
    "unique_users": ("usernames", "nunique"),
    "without_events_records": ("events", lambda x: x.isnull().mean()),
    "without_events_users": ("usernames", lambda x: x.groupby(x).filter(lambda y: df.loc[y.index, "events"].isnull().all()).nunique())
})

运行结果:

total_records  unique_users  without_events_records  without_events_users
clients                                                                            
client1               3             2                0.666667                     1
client2               2             2                0.500000                     1
client3               1             1                1.000000                     1

说明

  • 原代码中without_events_records的逻辑有误,x.notnull().mean()统计的是有事件记录的占比,若需统计无事件记录占比,应改为x.isnull().mean()。
  • 可根据实际业务需求选择对应场景的实现方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:20:22