我有一个包含字符串的Spark数据帧,我使用Likert量表将这些字符串与数字分数进行匹配。不同的问题id对应不同的分数。我尝试在Apache Spark udf中的Scala范围内进行模式匹配,使用这个问题作为指导:
如何在Scala的一个范围内进行模式匹配?
但是当我使用范围而不是简单的OR语句时,我遇到了编译错误,即
<code>31|32| 33|;34
31 到 35
无法编译。任何想法,我在语法上出错了吗?
此外,在最后一种情况下,我希望映射到字符串而不是Int,case_=
想必这是Spark的一个共性问题,因为在原生Scala中完全有可能返回< code>Any
?
这是我的代码:
def calculateScore = udf((questionId: Int, answerText: String) => (questionId, answerText) match {
case ((31 | 32 | 33 | 34 | 35), "Rarely /<br>Never") => 4 //this is fine
case ((31 | 32 | 33 | 34 | 35), "Occasionally") => 3
case ((31 | 32 | 33 | 34 | 35), "Often") => 2
case ((31 | 32 | 33 | 34 | 35), "Almost always /<br>Always") => 1
case ((x if 41 until 55 contains x), "None of the time") => 1 //this line won't compile
case _ => 0 //would like to map to "None"
})
然后,udf用于Spark数据帧,如下所示:
val df3 = df.withColumn("NumericScore", calculateScore(df("QuestionId"), df("AnswerText")))
如果您想将最后一个case
,即case_
映射为“无”String
,那么所有的case都应该返回String
以及
遵循udf
函数应该适合您
def calculateScore = udf((questionId: Int, answerText: String) => (questionId, answerText) match {
case ((31 | 32 | 33 | 34 | 35), "Rarely /<br>Never") => "4" //this is fine
case ((31 | 32 | 33 | 34 | 35), "Occasionally") => "3"
case ((31 | 32 | 33 | 34 | 35), "Often") => "2"
case ((31 | 32 | 33 | 34 | 35), "Almost always /<br>Always") => "1"
case (x, "None of the time") if (x >= 41 && x < 55) => "1" //this line won't compile
case _ => "None"
})
如果要将最后一个事例
(即 case _
映射到 None
),则需要将其他返回类型更改为 Option 的子级
,因为 None
是 Option 的子级
以下代码也应该适合您
def calculateScore = udf((questionId: Int, answerText: String) => (questionId, answerText) match {
case ((31 | 32 | 33 | 34 | 35), "Rarely /<br>Never") => Some(4) //this is fine
case ((31 | 32 | 33 | 34 | 35), "Occasionally") => Some(3)
case ((31 | 32 | 33 | 34 | 35), "Often") => Some(2)
case ((31 | 32 | 33 | 34 | 35), "Almost always /<br>Always") => Some(1)
case (x, "None of the time") if (x >= 41 && x < 55) => Some(1) //this line won't compile
case _ => None
})
最后一点是,您有 java.lang.不受支持的错误消息操作异常:不支持类型 Any 的架构
明确指出不支持返回类型为 Any
的 udf
函数不受支持。匹配案例
中的所有返回类型
都应保持一致。
保护表达式应放在模式之后:
def calculateScore = udf((questionId: Int, answerText: String) => (questionId, answerText) match {
case ((31 | 32 | 33 | 34 | 35), "Rarely /<br>Never") => 4
case ((31 | 32 | 33 | 34 | 35), "Occasionally") => 3
case ((31 | 32 | 33 | 34 | 35), "Often") => 2
case ((31 | 32 | 33 | 34 | 35), "Almost always /<br>Always") => 1
case (x, "None of the time") if 41 until 55 contains x => 1
case _ => 0 //would like to map to "None"
})
我尝试使用I forest https://github.com/titicaca/spark-iforest,的scala实现,但是当我构建时(就像README中报告的< code>mvn clean package),它给我这些错误: 有人知道为什么吗?谢谢 scala版本2.11.12 火花版本2.4.0 maven版本3.5.2 我修改了pom.xml,调整了scala、spark和mav
如何将多个列对分解为多行? 我有一个包含以下内容的数据帧 我想要一个最终的数据帧,如下所示 我试着使用下面的代码,但是它返回了4条记录,而不是我想要的两条记录
我有一个用斯卡拉写的UDF,我希望能够通过Pyspark会话调用它。UDF 采用两个参数:字符串列值和第二个字符串参数。我已经能够成功地调用UDF,如果它只需要一个参数(列值)。如果需要多个参数,我很难调用UDF。以下是到目前为止我在斯卡拉和Pyspark中能够做的事情: Scala UDF: 在Scala中使用它时,我已经能够注册和使用这个UDF: Scala主类: 以上工作成功。下面是Pysp
将现有应用程序从Spark 1.6移动到Spark 2.2*(最终)会导致错误“org.apache.spark.SparkExctive:任务不可序列化”。我过于简化了我的代码,以演示同样的错误。代码查询拼花文件以返回以下数据类型:“org.apache.spark.sql.数据集[org.apache.spark.sql.行]”我应用一个函数来提取字符串和整数,返回字符串。一个固有的问题与Sp
我有一个要求,火花UDF必须超载,我知道UDF超载是不支持火花。因此,为了克服spark的这一限制,我尝试创建一个接受任何类型的UDF,它在UDF中找到实际的数据类型,并调用相应的方法进行计算并相应地返回值。这样做时,我得到一个错误 以下是示例代码: 有可能使上述要求成为可能吗?如果没有,请建议我一个更好的方法。 注:Spark版本-2.4.0
我在火花数据帧中有一个“结构类型”列,它有一个数组和一个字符串作为子字段。我想修改数组并返回相同类型的新列。我可以用UDF处理它吗?或者有什么替代方案? 似乎我需要行类型的UDF,类似 这是有意义的,因为Spark不知道返回类型的模式。不幸的是,udf.register也失败了: