CSV文件分组去重:统计广告点赞最多的Top User_id
解决CSV用户广告点赞Top统计问题
看起来你已经精准定位到了问题——CSV数据存在重复项,接下来咱们一步步实现「统计每个用户的广告点赞次数,找出Top用户」的需求。
核心思路
我们需要完成几个关键步骤:
- 按
userId对所有记录分组 - 统计每个用户分组中
likedAd = true的总次数 - 按点赞次数降序排序,取出Top N用户
代码实现与解释
基于你现有的processCSV函数,我们可以直接链式调用Scala集合的API来实现需求:
方式1:直观分组统计(适合中小数据量)
// 读取CSV数据 val origFile = processCSV("src/main/resources/advert-data.csv") // 1. 按userId分组 → 统计每个用户的点赞次数 → 转成列表排序 → 取Top5 val topLikedUsers = origFile .groupBy(_.userId) // 将相同userId的记录归为一组,得到Map[Int, List[AdvertInfo]] .mapValues { records => // 这里有两种统计逻辑,根据你的业务需求二选一: records.count(_.likedAd) // ① 不去重:所有likedAd=true的记录都计入次数(适合重复是有效行为的场景) // records.distinct.count(_.likedAd) // ② 去重:重复的完全相同记录只算一次(适合重复是误导入的场景) } .toList // 转成List[(Int, Int)],格式为(userId, 点赞次数) .sortBy { case (userId, count) => (-count, userId) } // 按点赞次数降序,次数相同则按userId升序 .take(5) // 取点赞次数最多的前5个用户,按需调整数量 // 打印结果 topLikedUsers.foreach { case (id, cnt) => println(s"用户ID: $id,点赞次数: $cnt") }
方式2:单次遍历统计(适合大数据量,更高效)
如果你的CSV数据量很大,groupBy会生成中间列表占用内存,这时可以用foldLeft单次遍历完成统计:
val userLikeCounts = origFile.foldLeft(Map.empty[Int, Int]) { (accMap, info) => val currentCount = accMap.getOrElse(info.userId, 0) // 如果当前记录是点赞,次数+1,否则保持原次数 val newCount = if (info.likedAd) currentCount + 1 else currentCount accMap.updated(info.userId, newCount) } // 后续排序取Top的逻辑和方式1一致 val topLikedUsers = userLikeCounts.toList .sortBy { case (id, cnt) => (-cnt, id) } .take(5)
关键细节说明
- 重复数据处理:代码中给出了两种统计逻辑,你需要根据业务场景选择:
- 如果重复记录是用户的有效重复点赞行为(比如多次点击广告),用
records.count(_.likedAd) - 如果重复记录是数据导入错误导致的完全重复项,用
records.distinct.count(_.likedAd)
- 如果重复记录是用户的有效重复点赞行为(比如多次点击广告),用
- 排序逻辑:
sortBy { case (id, cnt) => (-count, userId) }保证了先按点赞次数降序,次数相同时按userId升序,避免排序结果不稳定。
内容的提问来源于stack exchange,提问作者monkeys73
相关产品推荐
相关产品推荐

