Spark udf用于从现有列创建新列,以及使用group by

时间:2017-07-12 19:43:06

标签: scala apache-spark dataframe apache-spark-sql user-defined-functions

我有一个包含以下列的数据框:group_id,gender和height。

group_id和height是Int。 性别是字符串。

group_id| gender|height
 1      |  F    |  52
 1      |  F    |  53
 1      |  F    |  58 
 1      |  M    |  55
 1      |  M    |  59
 2      |  F    |  50
 2      |  M    |  60
 2      |  M    |  61
 2      |  M    |  64

我想按group_id,gender和height_range进行分组 高度范围可以是任何值,但是是预定义的 - 例如48-50,51-58,58-64等。 为简单起见,我在考虑增加5英寸:50-54,55-59,60-64。

预期产出:

group_id | gender | height_low | height_high | count
   1     | F      |    50      |    54       |   2
   1     | F      |    55      |    59       |   1
   1     | M      |    55      |    59       |   2
   2     | F      |    50      |    54       |   1
   2     | M      |    60      |    64       |   3

我尝试使用sum(when)。这对获得低价值和高价值没有多大帮助。 我能想到的另一种方法是使用hive udf 2次,一次用when子句中的各种条件填充height_low,另一次填充height_high。 我想知道是否有办法同时填充这两个,因为我需要执行相同的检查。 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

您可以使用floor结果的height / 5(四舍五入)作为分组的关键字(以及其他列),然后计算height_low和{{ 1}}如有必要:

height_high

编辑:更一般的情况,范围不一定是常量,确实可以使用返回表示范围的元组的UDF来解决:

import org.apache.spark.sql.functions._
import spark.implicits._

val result = df.groupBy($"group_id", $"gender", floor($"height" / 5) * 5 as "height_low")
  .count()
  .withColumn("height_high", $"height_low" + 4)