Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何基于一组列值更新Spark Dataframe中的列?_Scala_Apache Spark_Dataframe - Fatal编程技术网

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。非常感谢!