【问题标题】:scala find top-k elements for a keyed sequencescala 查找键控序列的前 k 个元素
【发布时间】:2020-02-22 19:12:43
【问题描述】:

对于第一个元素构成键的一系列事物:

val things = Seq(("key_1", ("first", 1)),("key_1", ("first_second", 11)), ("key_2", ("second", 2)))

我想计算一个键出现的频率,然后只保留前 k 个元素。

在 pandas 或数据库中我会:

  1. 计数
  2. 将结果加入到原始和过滤器中

在 Scala 中,第一部分可以通过以下方式处理:

things.groupBy(identity).mapValues(_.size)

这里的第一位是:

things.groupBy(_._1).mapValues(_.map( _._2 ))

但我不确定第二步。 在上面的例子中,当查看 top-1 键时,key_1 出现两次,因此被选中。 期望的输出结果是前 k 个关键元组的第二个元素:

Seq(("first", 1),("first_second", 11))

编辑

我需要一个适用于 2.11.x 的解决方案。

【问题讨论】:

  • 对不起,这确实是最小示例中的错字 - 我已经更新了它。

标签: scala seq


【解决方案1】:

这种方法首先按键分组以获得原始项目的键映射。

您还可以使用 OrderedMap 或 PriorityQueue 进行更高效的 top-N 计算,但如果元素不多,那么简单的 sortBy 也可以,如图所示。

def valuesOfNMostFrequentKeys(things: Seq[(String, (String, Int))], N: Int = 1) = {
    val grouped: Map[String,Seq[(String, (String, Int))]] = things.groupBy(_._1)

    // "map" array of counts per keys to KV Tuples 
    val countToTuples:Array[(Int, Seq[(String, (String, Int))])]  = grouped.map((kv: (String, Seq[(String, (String, Int))])) => (kv._2.size, kv._2)).toArray
    // sort by count (first item in tuple) descending and take top N
    val sortByCount:Array[(Int, Seq[(String, (String, Int))])] = countToTuples.sortBy(-_._1)
    val topN:Array[(Int, Seq[(String, (String, Int))])] = sortByCount.take(N)

    // extract inner (String, Int) item from list of keys and values, and flatten
    topN.flatMap((kvList: (Int, Seq[(String, (String, Int))])) => kvList._2.map(_._2))
}

valuesOfNMostFrequentKeys(things)

输出:

valuesOfNMostFrequentKeys: (things: Seq[(String, (String, Int))], N: Int)Array[(String, Int)]
res44: Array[(String, Int)] = Array((first,1), (first_second,11))

注意上面是一个数组,你可能想做toSeq——但这在 Scala 2.11 中有效。

【讨论】:

【解决方案2】:

看起来像:

things.groupBy(_._1)
  .mapValues(e => (e.map(_._2).size, e.map(_._2))).toSeq.map(_._2)
  .sortBy(_._1).reverse.take(2).flatMap(_._2)

计算所需的输出

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 2021-05-16
    • 2019-08-20
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    相关资源
    最近更新 更多