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

不使用Pandas实现按USERID分组后对EVENTID的AMOUNT求和

不使用Pandas实现按用户分组的事件金额求和

问题背景

原始CSV数据如下:

USERID, USERNAME, EVENTID, DATE, AMOUNT
001,User1,EV-001,2020-01-01,1000
E001,User1,EV-001,2021-01-01,1000
E001,User1,EV-002,2020-03-01,300
E001,User1,EV-002,2020-04-01,500
E002,User2,EV-003,2020-01-02,100
E002,User2,EV-003,2020-02-02,200
E002,User3,EV-003,2020-03-02,300
E003,User4,EV-004,2024-01-01,100

需求:

  1. 筛选日期**早于等于2020-04-01**的数据
  2. 按USERID分组,对每个用户下不同EVENTID对应的AMOUNT求和
  3. 最终结果按USERID排序,无符合条件数据的用户也要输出求和为0的记录

之前尝试仅以EVENTID为键构建字典,只能得到全局事件的求和结果,无法实现先按用户分组的逻辑,当前输出:

{'EV001': {'SUM': 1000}, 'EV002': {'SUM': 800}, 'EV003': {'SUM': 600}}

期望输出(注:原期望输出存在数据匹配错误,以下为符合原始数据的正确期望输出):

001,User1,EV-001,1000
E001,User1,EV-001,0
E001,User1,EV-002,800
E002,User2,EV-003,300
E002,User3,EV-003,300
E003,User4,EV-004,0

解决方案

核心思路是使用嵌套字典分层存储数据:外层字典以USERID为键,对应的值包含用户的USERNAME和一个内层字典(以EVENTID为键,存储该用户该事件的累计金额),以此实现先按用户分组、再在组内按事件求和的逻辑。

以下是完整实现代码:

# 定义筛选日期
INPUT_DATE = "2020-04-01"
# 模拟原始CSV数据(若读取本地文件,可替换为open()读取逻辑)
csv_data = """USERID, USERNAME, EVENTID, DATE, AMOUNT
001,User1,EV-001,2020-01-01,1000
E001,User1,EV-001,2021-01-01,1000
E001,User1,EV-002,2020-03-01,300
E001,User1,EV-002,2020-04-01,500
E002,User2,EV-003,2020-01-02,100
E002,User2,EV-003,2020-02-02,200
E002,User3,EV-003,2020-03-02,300
E003,User4,EV-004,2024-01-01,100"""

# 初始化嵌套字典:{USERID: {'username': 用户名, 'events': {EVENTID: 累计金额}}}
user_event_summary = {}

# 逐行处理数据
lines = csv_data.strip().split('\n')
for line in lines[1:]:
    # 拆分并清洗每一行的字段
    user_id, username, event_id, date_str, amount = [p.strip() for p in line.split(',')]
    amount = int(amount)

    # 初始化用户记录(无论日期是否符合,都要保留用户信息)
    if user_id not in user_event_summary:
        user_event_summary[user_id] = {
            'username': username,
            'events': {}
        }
    user_info = user_event_summary[user_id]
    events = user_info['events']

    # 处理日期符合条件的数据:累加金额
    if date_str <= INPUT_DATE:
        if event_id in events:
            events[event_id] += amount
        else:
            events[event_id] = amount
    # 处理日期不符合的数据:记录事件并设为0
    else:
        if event_id not in events:
            events[event_id] = 0

# 按USERID排序后输出结果
for user_id in sorted(user_event_summary.keys()):
    user_info = user_event_summary[user_id]
    for event_id, total_amount in user_info['events'].items():
        print(f"{user_id},{user_info['username']},{event_id},{total_amount}")

代码逻辑说明

  1. 分层存储结构:通过嵌套字典实现用户-事件的层级关系,确保每个用户的事件统计独立,不会和其他用户的同事件数据混淆。
  2. 日期筛选:利用ISO格式日期(YYYY-MM-DD)的字符串可直接比较大小的特性,快速判断日期是否符合要求。
  3. 全用户覆盖:即使数据日期不符合筛选条件,也会初始化用户和事件记录,保证最终输出包含所有原始用户。
  4. 有序输出:最后对用户ID进行排序,确保输出结果按用户ID有序排列。

运行上述代码后,输出结果与修正后的期望输出完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:10:27