我需要在Spark DataFrame
SELECT KEY,
CASE WHEN tc in ('a','b') THEN 'Y'
WHEN tc in ('a') AND amt > 0 THEN 'N'
ELSE NULL END REASON,
FROM dataset1;
我的输入DataFrame
如下:
val dataset1 = Seq((66, "a", "4"), (67, "a", "0"), (70, "b", "4"), (71, "d", "4")).toDF("KEY", "tc", "amt")
dataset1.show()
+---+---+---+
|KEY| tc|amt|
+---+---+---+
| 66| a| 4|
| 67| a| 0|
| 70| b| 4|
| 71| d| 4|
+---+---+---+
我在语句为:
时实现了嵌套大小写dataset1.withColumn("REASON", when(col("tc").isin("a", "b"), "Y")
.otherwise(when(col("tc").equalTo("a") && col("amt").geq(0), "N")
.otherwise(null))).show()
+---+---+---+------+
|KEY| tc|amt|REASON|
+---+---+---+------+
| 66| a| 4| Y|
| 67| a| 0| Y|
| 70| b| 4| Y|
| 71| d| 4| null|
+---+---+---+------+
上述逻辑的可读性"否则"如果嵌套的when语句更进一步,语句有点乱。
在Spark DataFrames
中的语句有没有更好的方法来实现嵌套大小写?
答案 0 :(得分:14)
这里没有嵌套,因此不需要endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
。您所需要的只是链接otherwise
:
when
import spark.implicits._
when($"tc" isin ("a", "b"), "Y")
.when($"tc" === "a" && $"amt" >= 0, "N")
是隐含的,因此您可以完全省略它。
您使用的模式更适用于ELSE NULL
数据结构:
folding
其中val cases = Seq(
($"tc" isin ("a", "b"), "Y"),
($"tc" === "a" && $"amt" >= 0, "N")
)
- when
自然遵循递归模式,otherwise
提供基本情况。
null
请注意,在这一系列条件下,达到“N”结果是不可能的。如果cases.foldLeft(lit(null)) {
case (acc, (expr, value)) => when(expr, value).otherwise(acc)
}
等于“a”,则第一个子句将捕获它。如果不是,它将无法满足两个谓词并默认为tc
。你应该宁愿:
NULL
答案 1 :(得分:2)
对于更复杂的逻辑,我更喜欢使用UDF来提高可读性:
val selectCase = udf((tc: String, amt: String) =>
if (Seq("a", "b").contains(tc)) "Y"
else if (tc == "a" && amt.toInt <= 0) "N"
else null
)
dataset1.withColumn("REASON", selectCase(col("tc"), col("amt")))
.show
答案 2 :(得分:0)
您只需在数据集上使用selectExpr
dataset1.selectExpr("*", "CASE WHEN tc in ('a') AND amt > 0 THEN 'N' WHEN tc in ('a','b') THEN 'Y' ELSE NULL END
REASON").show()
+---+---+---+------+
|KEY| tc|amt|REASON|
+---+---+---+------+
| 66| a| 4| N|
| 67| a| 0| Y|
| 70| b| 4| Y|
| 71| d| 4| null|
+---+---+---+------+
第二个条件应该放在第一个条件之前,因为第一个条件更通用。
当tc((a))和amt> 0则为'N'</ p>