首页 > 解决方案 > 在 csv 文件中对重复项进行分组

问题描述

我有一个 CSV 文件,我将一个案例类应用到该文件上并制作成一个列表,例如

CSV 文件是这样的 -

"user_id","age","liked_ad","location"
2145,34,true,USA
6786,25,true,UK
9025,21,false,USA
1145,40,false,UK

它继续。最终,我试图找到拥有最喜欢的广告(真实值)的顶级用户 ID。我知道 csv 文件中存在重复项 -

val origFile = processCSV("src/main/resources/advert-data.csv")
val origFileLength = origFile.length

val uniqueList = origFile.distinct
val uniqueListLength = uniqueList.length

两种长度不同。我想我需要对所有 user_id 进行分组,以便相同 user_id 的所有条目都在一个组中,然后我可以计算该用户条目中有多少“真”。我完全被困在解决这个问题的正确方法上。

这是我目前的 processCSV 功能-

final case class AdvertInfo(userId: Int, age: Int, likedAd: Boolean, location: String)

    def processCSV(file: String): List[AdvertInfo] = {
      val data = io.Source.fromFile(file)

      data
        .getLines()
        .map(_.split(',').iterator.map(_.trim).toList)
        .flatMap {
          case userIdRaw :: ageRaw :: likedAdRaw :: locationRaw :: Nil =>
            for {
              userId <- userIdRaw.toIntOption
              age <- ageRaw.toIntOption
              likedAd <- likedAdRaw.toBooleanOption
              location <- Some(locationRaw)
            } yield AdvertInfo(userId, age, likedAd, location)
          case _ =>
            None
        }.toList
    }

标签: scalacsv

解决方案


您的描述有点令人困惑,但我认为您想要的是:

origFile.filter(_.likedAd)
        .groupMapReduce(_.userId)(_ => 1)(_+_) //Scala 2.13.x

结果是 a Map,其中user_ids 作为键,所有liked_ad=="true" 的计数作为值。

您可以从那里.toList.sortBy(-_._2)获得按喜欢计数的排名。


推荐阅读