2016-12-21 10 views
2

列のセットの最も頻繁な値を見つけ出すためのより効率的な方法が、rank()を使用するよりも不足している値の代用として使用するよりも、 。sparkが列のセットで最も頻繁に値を見つける

など。 spark-sqlで、私は how to select the most frequently appearing values? 列のようなものを公式化することができました。 このソリューションは、ランクを使用して単一の列で機能します。私が探しているのは、a)より効率的なバリアント(最初の解説のアウトライン)とb)forループとa)のソリューションを複数の列に適用するよりも最適なものです。

sparkでこれを最適化する可能性はありますか?

編集

例です。ここに答え

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) 

からの問合せでは、小さなデータセット

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)) 

は結果であるが、列のバーのためにされる - >まず、バズ - > Aとdrompe用 - > fooが単一TOP1です返される結果と異なる最も頻繁な値。

答えて

1

あなたは限り、あなたのフィールドを注文することができ、カウントは先頭の1であるような単純な集計を使用することができます。

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 
) 

あなたをより複雑なシナリオを処理するためのグループ化の列やキー機能を調整できます。

関連する問題