DataFrameの列のパーセンタイルを計算しようとしていますか? Spark集計関数にpercentile_approx関数が見つかりません。
例: Hiveにはpercentile_approxがあり、次のように使用できます
hiveContext.sql("select percentile_approx("Open_Rate",0.10) from myTable);
しかし、パフォーマンス上の理由から、Spark DataFrameを使用して実行したいと思います。
サンプルデータセット
|User ID|Open_Rate|
-------------------
|A1 |10.3 |
|B1 |4.04 |
|C1 |21.7 |
|D1 |18.6 |
10パーセンタイルや20パーセンタイルなどに分類されるユーザーの数を知りたいです。こんなことしたい
df.select($"id",Percentile($"Open_Rate",0.1)).show
Spark2.0以降、作業が簡単になりました。次のようなDataFrameStatFunctionsでこの関数を使用するだけです。
df.stat.approxQuantile("Open_Rate",Array(0.25,0.50,0.75),0.0)
DataFrameStatFunctionsには、DataFrameに役立つ統計関数もいくつかあります。
SparkSQLとScalaデータフレーム/データセットAPIは同じエンジンで実行されます。同等の操作で同等の実行プランが生成されます。実行プランはexplain
で確認できます。
_sql(...).explain
df.explain
_
特定の質問になると、SparkSQLとScala DSL構文を混在させるのが一般的なパターンです。これは、ご存知のとおり、それらの機能はまだ同等ではないためです(別の例は、 SQLのexplode()
とDSLのexplode()
。後者はより強力ですが、マーシャリングのために非効率的です。)
それを行う簡単な方法は次のとおりです。
_df.registerTempTable("tmp_tbl")
val newDF = sql(/* do something with tmp_tbl */)
// Continue using newDF with Scala DSL
_
簡単な方法を使用する場合に留意する必要があるのは、一時テーブル名がクラスターグローバル(最大1.6.x)であるということです。したがって、コードが同じクラスター上で複数回同時に実行される可能性がある場合は、ランダム化されたテーブル名を使用する必要があります。
私のチームでは、パターンは一般的です-DataFrame
に暗黙の.sql()
を追加しました。これにより、SQLステートメントのスコープの一時テーブルが自動的に登録および登録解除されます。