Scala 如何基于一组列值更新Spark Dataframe中的列?
我有一个数据框架,其部门值必须来自给定的一组值Scala 如何基于一组列值更新Spark Dataframe中的列?,scala,apache-spark,dataframe,Scala,Apache Spark,Dataframe,我有一个数据框架,其部门值必须来自给定的一组值 ----------------------- Id Name Department ----------------------- 1 John Sales 2 Martin Maintenance 3 Keith Sales 4 Rob Unknown 5 Kevin Unknown 6 Peter Maintenance ------------------------ Departmen
-----------------------
Id Name Department
-----------------------
1 John Sales
2 Martin Maintenance
3 Keith Sales
4 Rob Unknown
5 Kevin Unknown
6 Peter Maintenance
------------------------
Department的有效值存储在字符串数组中。
[“销售”、“维护”、“培训”]
如果数据框中的部门值不是允许的值,则必须将其替换为“培训”。因此,新的数据帧将是-
-----------------------
Id Name Department
-----------------------
1 John Sales
2 Martin Maintenance
3 Keith Sales
4 Rob Training
5 Kevin Training
6 Peter Maintenance
------------------------
什么是可行的解决方案?您可以通过使用
when/other
、concat
和lit
内置函数来实现您的需求
val validDepartments = Array("Sales","Maintenance","Training")
import org.apache.spark.sql.functions._
df.withColumn("Department", when(concat(validDepartments.map(x => lit(x)):_*).contains(col("Department")), col("Department")).otherwise("Training")).show(false)
应该给你什么
+---+------+---+-----------+
|Id |Name |Age|Department |
+---+------+---+-----------+
|1 |John |35 |Sales |
|2 |Martin|34 |Maintenance|
|3 |Keith |33 |Sales |
|4 |Rob |34 |Training |
|5 |Kevin |35 |Training |
|6 |Peter |36 |Maintenance|
+---+------+---+-----------+
一个简单的udf
函数也可以满足您的需求
val validDepartments = Array("Sales","Maintenance","Training")
import org.apache.spark.sql.functions._
def containsUdf = udf((department: String) => validDepartments.contains(department) match {case true => department; case false => "Training"} )
df.withColumn("Department", containsUdf(col("Department"))).show(false)
这会给你同样的结果
我希望答案是有帮助的你好,拉梅什,你的答案很有帮助。但是如果validDepartments是从不同的数据帧创建的呢。它类似于-validDepartments=someDf.select(“department”).collect().map(u.toString)。除此之外,上面还将创建一个数组[String]。但是当我使用这个时,containsUdf并没有给出预期的结果。它将所有字段替换为值“Training”。错误在于,您在每一行上调用toString,这会将方括号附加到行中。您可以使用getAs。因此,您可以执行
val validDepartments=someDf.select(“department”).collect().map(uu.getAs[String](“department”).distinct
,然后使用这个validDepartments,您应该是完美的;)令人惊叹的。这正是我要找的。你能解释一下为什么validDepartments=someDf.select(“department”).collect().map(u.toString)。尽管validDepartments在这两种情况下都是数组[String]类型,也就是说,即使使用了getAs,也不使用它。如果你看数组(“[Sales]”,“[Training]”
和数组(“Sales”),“Training”)
两者都是Array[String]
但你可以决定它们是否相等;)我知道两者都不相等。我想我现在明白了为什么我们使用getAs。非常感谢!