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

UDF to randomly assign values based on different probabilities

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

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

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

这里没有发生意外。你调用 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"))