我想知道是否有一种更有效的方法可以找到一组列中最常用的值,而不是使用rank()
来将其用作缺失值的插补。
E.g。在spark-sql中,我可以制定类似的东西 how to select the most frequently appearing values? 每列。 此解决方案适用于使用排名的单个列。我正在寻找的是a)一个更有效的变体(作为第一个答案轮廓)和b)比使用for循环和a)的解决方案更适合申请多个列的东西。
你认为有可能在火花中优化它吗?
一个例子。这是一个小型数据集
case class FooBarGG(foo: Int, bar: String, baz: String, dropme: String)
val df = Seq((0, "first", "A", "dropme"), (1, "second", "A", "dropme2"),
(0, "first", "B", "foo"),
(1, "first", "C", "foo"))
.toDF("foo", "bar", "baz", "dropme").as[FooBarGG]
val columnsFactor = Seq("bar", "baz")
val columnsToDrop = Seq("dropme")
val factorCol= (columnsFactor ++ columnsToDrop).map(c => col(c))
使用答案中的查询
df.groupBy(factorCol: _*).count.agg(max(struct($"count" +: factorCol: _*)).alias("mostFrequent")).show
+--------------------+
| mostFrequent|
+--------------------+
|[1,second,A,dropme2]|
+--------------------+
|-- mostFrequent: struct (nullable = true)
| |-- count: long (nullable = false)
| |-- bar: string (nullable = true)
| |-- baz: string (nullable = true)
| |-- dropme: string (nullable = true)
结果但是对于栏栏 - >首先,baz - > A和drompe - > foo是单个top1最常见的值,与返回的结果不同。
答案 0 :(得分:2)
只要您可以订购字段并且count是最重要的字段,您就可以使用简单聚合:
import org.apache.spark.sql.functions._
val df = Seq("John", "Jane", "Eve", "Joe", "Eve").toDF("name")
val grouping = Seq($"name")
df.groupBy(grouping: _*).count.agg(max(struct($"count" +: grouping: _*)))
也可以使用静态类型Dataset
:
import org.apache.spark.sql.catalyst.encoders.RowEncoder
df.groupByKey(x => x)(RowEncoder(df.schema)).count.reduce(
(x, y) => if (x._2 > y._2) x else y
)
您可以调整分组列或键功能以处理更复杂的情况。