ОБНОВЛЕНИЕ
Я обнаружил функцию percentile_approx
в контексте улья, поэтому вам не нужно использовать функции stat
.
val states = Seq("CA", "AZ")
val cols = Seq("con_dist_1", "con_dist_2")
val l = cols.map(c => expr(s"percentile_approx($c, Array(0.25, 0.5, 0.75)) as ${c}_quantiles"))
val df2 = df.filter($"state".isin(states: _*)).groupBy("state").agg(l.head, l.tail: _*)
df2.select(col("state") +: cols.flatMap( c => (1 until 4).map( i => col(c + "_quantiles")(i - 1).alias(c + "_quantile_" + i))): _*).show(false)
Здесь я попробовал автоматизированный метод для данных states
и cols
. Результат будет:
+-----+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
|state|con_dist_1_quantile_1|con_dist_1_quantile_2|con_dist_1_quantile_3|con_dist_2_quantile_1|con_dist_2_quantile_2|con_dist_2_quantile_3|
+-----+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
|AZ |4 |4 |4 |0.816039063 |0.816039063 |0.816039063 |
|CA |4 |4 |6 |0.019875458 |0.082049528 |0.816039063 |
+-----+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
Имейте в виду, что результат немного отличается от ожидаемого, потому что я установил states = Seq("CA", "AZ")
, который вы дали.
ORIGINAL
Используйте Window
для состояний и рассчитайте percent_rank
для каждого столбца.
import org.apache.spark.sql.expressions.Window
val w1 = Window.partitionBy("state").orderBy("con_dist_1")
val w2 = Window.partitionBy("state").orderBy("con_dist_2")
df.withColumn("p1", percent_rank.over(w1))
.withColumn("p2", percent_rank.over(w2))
.show(false)
Вы можете сначала отфильтровать кадр данных, только для указанных c состояния. В любом случае, результат:
+---+---------+-----------+----------+-----------+-----+---+---+
|id |date |revenue |con_dist_1|con_dist_2 |state|p1 |p2 |
+---+---------+-----------+----------+-----------+-----+---+---+
|10 |1/15/2018|0.006628853|4 |0.816039063|AZ |0.0|0.0|
|10 |1/15/2018|0.006628853|4 |0.816039063|AZ |0.0|0.0|
|10 |1/15/2018|0.010680705|6 |0.019875458|CA |1.0|0.0|
|10 |1/15/2018|0.01378215 |4 |0.082049528|CA |0.0|0.5|
|10 |1/15/2018|0.006628853|4 |0.816039063|CA |0.0|1.0|
|10 |1/15/2018|0.010680705|6 |0.019875458|TX |0.5|0.0|
|10 |1/15/2018|0.010680705|6 |0.019875458|TX |0.5|0.0|
|10 |1/15/2018|0.01378215 |4 |0.082049528|TX |0.0|1.0|
+---+---------+-----------+----------+-----------+-----+---+---+