Apache Spark案例在不同的列上具有多个when子句

Ban*_*ddy 2 hadoop apache-spark apache-spark-sql

给出以下结构:

val df = Seq("Color", "Shape", "Range","Size").map(Tuple1.apply).toDF("color")

val df1 = df.withColumn("Success", when($"color"<=> "white", "Diamond").otherwise(0))
Run Code Online (Sandbox Code Playgroud)

我想再写一个WHEN条件,上面的条件是大小> 10,并且Shape列的值为Rhombus,然后将“ Diamond”值插入该列,否则为0。我尝试如下所示,但失败了

val df1 = df.withColumn("Success", when($"color" <=> "white", "Diamond").otherwise(0)).when($"size">10)
Run Code Online (Sandbox Code Playgroud)

请建议我仅使用scala的dataframe选项。带有sqlContext的Spark-SQL对我没有帮助。

谢谢 !

jga*_*gaw 6

您可以whenhttps://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Column.html#when-org.apache.spark.sql.Column中链接类似于示例的示例-java.lang.Object- 自(1.4.0)可用

// Scala:
people.select(when(people("gender") === "male", 0)
 .when(people("gender") === "female", 1)
 .otherwise(2))
Run Code Online (Sandbox Code Playgroud)

你的例子:

val df1 = df.withColumn("Success",
  when($"color" <=> "white", "Diamond")
  .when($"size" > 10 && $"shape" === "Rhombus", "Diamond")
  .otherwise(0))
Run Code Online (Sandbox Code Playgroud)


dbu*_*osp 0

您尝试过制作 UDF 吗?尝试这样的事情:

// Define the UDF
val isDiamond= udf((color: String, shape: String, size : String) => {
  if (color == "white" && shape == "Rhombus" && size > 10) "Diamond"
  else ""
})
val df2 = df.withColumn("Success", isDiamond($"color", $"shape", $"size"))
Run Code Online (Sandbox Code Playgroud)

问候。

  • -1 这个答案。AFAIK,您应该始终避免使用 UDF 来完成任何可以通过链接结构化 API 中的现有语句来解决的任务,无论您的代码看起来有多长或多复杂。原因是Spark的Catalyst优化器在基于Structured API时会极大地改进你的代码,但是当它发现UDF时它是盲目的,这对于Spark来说就像一个不可优化的黑匣子。 (2认同)