UDF根据不同的概率随机分配值
UDF to randomly assign values based on different probabilities
我想创建一个 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
这里没有发生意外。你调用 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"))
我想创建一个 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
这里没有发生意外。你调用 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"))