我正在尝试使用udf
和一个表示实际正则表达式的附加参数来对照正则表达式检查scala数据帧的一列。
但是,似乎不允许将正则表达式放入lit()
语句中引发以下错误
java.lang.RuntimeException:不支持的文字类型类 scala.util.matching.Regex
使用下面的示例代码。我希望带有布尔条目的附加列“ DMY”。
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions._
import scala.util.matching._
def dateDMY_regex(): Regex = """^[0-3]?[0-9][-/.][0-1]?[0-9][-/.](19|20)?\d{2}$""".r
def date_match(value: String, dateEx: Regex): Boolean = {
return dateEx.unapplySeq(value).isDefined
}
val spark = SparkSession.builder().getOrCreate()
var df = spark.createDataFrame(Seq(
(0, "31/10/2018"),
(1, "01/11/2018"),
(2, "02/11/2018"))).toDF("Id", "col_1")
// to test the function
// print(date_match("31/10/2018", dateDMY_regex()))
val date_match_udf = udf(date_match _) //, lit("c")
df = df.withColumn( "DMY", date_match_udf( $"col_1", lit(dateDMY_regex()) ) )
df.show()
答案 0 :(得分:1)
您可以通过在UDF中进行计数来提供非列参数(即dateEx
的值),如下所示:
import org.apache.spark.sql.functions._
import scala.util.matching._
val df = spark.createDataFrame(Seq(
(0, "31/10/2018"),
(1, "999/11/2018"),
(2, "02/11/2018"))
).toDF("Id", "col_1")
val dateEx = """^[0-3]?[0-9][-/.][0-1]?[0-9][-/.](19|20)?\d{2}$""".r
def date_match_udf(dateEx: Regex) = udf(
(value: String) => dateEx.unapplySeq(value).isDefined
)
df.withColumn("DMY", date_match_udf(dateEx)($"col_1")).
show
// +---+-----------+-----+
// | Id| col_1| DMY|
// +---+-----------+-----+
// | 0| 31/10/2018| true|
// | 1|999/11/2018|false|
// | 2| 02/11/2018| true|
// +---+-----------+-----+
但是,为满足您的需求,我建议您使用通常性能更好的Spark内置函数而不是UDF。以下是使用regexp_extract
的一种方法:
val dateExStr = """^([0-3]?[0-9][-/.][0-1]?[0-9][-/.](19|20)?\d{2})$"""
df.withColumn("DMY", $"col_1" === regexp_extract($"col_1", dateExStr, 1)).
show
答案 1 :(得分:0)
我仍然无法通过正则表达式。现在,我的解决方法是通过字符串并在函数中进行编译。如下:
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions._
import scala.util.matching._
def dateDMY_regex(): String = """^[0-3]?[0-9][-/.][0-1]?[0-9][-/.](19|20)?\d{2}$"""
def date_match(value: String, dateEx: String): Boolean = {
return dateEx.r.unapplySeq(value).isDefined
}
val spark = SparkSession.builder().getOrCreate()
var df = spark.createDataFrame(Seq(
(0, "31/10/2018"),
(1, "01/11/2018"),
(2, "02/11/2018"))).toDF("Id", "col_1")
// to test the function
// print(date_match("31/10/2018", dateDMY_regex()))
val date_match_udf = udf(date_match _) //, lit("c")
df = df.withColumn( "DMY", date_match_udf( $"col_1", lit(dateDMY_regex()) ) )
df.show()