UDF根据不同的概率随机分配值

时间:2016-09-23 15:31:33

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

我想创建一个UDF,根据不同的概率随机分配值。

在以下示例中,取决于rand返回的值:

  • 0到0.5该值应为A(50%概率)
  • 0.8到1该值应为B(概率为20%)
  • 其他任何值应该是c(30%概率)

val names = Array("A", "B", "C")

val allocate = udf((p: Double) => {
    if(p < 0.5) names(0)
    else if (p > 0.8) names(1)
    else names(2)})

val test = sqlContext.range(0, 100).select(($"id"),(round(abs(rand),2)).alias("val"), allocate(abs(rand)).alias("name"))
`

但是,当我打印结果时,不会根据UDF中定义的规则分配名称。

+---+----+----+
| id| val|name|
+---+----+----+
|  0|0.17|   C| => should be A
|  1|0.12|   A|
|  2|0.36|   A|
|  3|0.56|   B|
|  4|0.82|   A|=> should be C

1 个答案:

答案 0 :(得分:3)

这里没有任何意外的事情发生。您将rand函数调用两次,以便获得两个不同的随机值。

为两个调用提供相同的种子:

sqlContext.range(0, 100)
  .select(
    $"id", 
    abs(rand(1)).alias("val"),
    allocate(abs(rand(1))).alias("name") 
  )

或重用该值:

sqlContext.range(0, 100)
  .withColumn("val", abs(rand))
  .withColumn("name", allocate($"val"))