Spark Scala-拆分字符串语法问题



我正在尝试使用SparkSQL和Scala拆分DataFrame列中的String,并且似乎在分离条件对两个的作用方式上存在差异

使用Scala、

这是有效的-

val seq = Seq("12.1")
val df = seq.toDF("val")

Scala代码->

val seq = Seq("12.1")
val df = seq.toDF("val")
val afterSplit = df2.withColumn("FirstPart", split($"val", "\.")).select($"FirstPart".getItem(0).as("PartOne"))
afterSplit.show(false)

然而,在Spark SQL中,当我使用它时,firstParkSQL显示一个空白。

df.registerTempTable("temp")
val s1 = sqlContext.sql("select split(val, '\.')[0] as firstPartSQL from temp")

相反,当我使用this(单独的条件表示为[.]而不是\。显示预期值。

val s1 = sqlContext.sql("select split(val, '[.]')[0] as firstPartSQL from temp")

你知道为什么会这样吗?

当您在带有双引号spark.sql(".....")的spark-sql中使用regex模式时,它被视为另一个字符串中的字符串,因此会发生两件事。考虑这个

scala> val df = Seq("12.1").toDF("val")
df: org.apache.spark.sql.DataFrame = [val: string]
scala> df.withColumn("FirstPart", split($"val", "\.")).select($"FirstPart".getItem(0).as("PartOne")).show
+-------+
|PartOne|
+-------+
|     12|
+-------+

scala> df.createOrReplaceTempView("temp")

使用df(),用于split的regex字符串直接传递给split字符串,因此您只需要单独转义反斜杠(\)。

但当涉及到spark-sql时,模式首先被转换为字符串,然后再次作为字符串传递给split()函数,因此,在sparksql中使用\.之前,您需要获得它

获得这一点的方法是再添加2个

scala> "\."
res12: String = .
scala> "\\."
res13: String = \.
scala>

如果您只是在spark-sql中传递"\.",首先它会被转换为.,然后转换为".",在regex上下文中,它会变成(.)"any"字符即,在任何字符上拆分,并且由于每个字符都相邻,因此会得到一个空字符串数组。字符串"12.1"的长度是四,它也与字符串的最终边界"$"匹配。。所以直到split(val,'\.')[4],你会得到空字符串。当您发布split(val,'\.,')[5]时,您将获得null

为了验证这一点,您可以将相同的分隔符字符串"\."传递给regex_replace()函数,看看会发生什么

scala> spark.sql("select split(val, '\.')[0] as firstPartSQL, regexp_replace(val,'\.','9') as reg_ex from temp").show
+------------+------+
|firstPartSQL|reg_ex|
+------------+------+
|            |  9999|
+------------+------+
scala> spark.sql("select split(val, '\\.')[0] as firstPartSQL, regexp_replace(val,'\\.','9') as reg_ex from temp").show
+------------+------+
|firstPartSQL|reg_ex|
+------------+------+
|          12|  1291|
+------------+------+

scala>

如果您仍然想在df和sql之间使用相同的模式,那么使用原始字符串,即三引号。

scala> raw"\."
res23: String = \.
scala>
scala> spark.sql("""select split(val, '\.')[0] as firstPartSQL, regexp_replace(val,'\.','9') as reg_ex from temp""").show
+------------+------+
|firstPartSQL|reg_ex|
+------------+------+
|          12|  1291|
+------------+------+

scala> spark.sql("""select split(val, "\.")[0] as firstPartSQL, regexp_replace(val,"\.",'9') as reg_ex from temp""").show
+------------+------+
|firstPartSQL|reg_ex|
+------------+------+
|          12|  1291|
+------------+------+

scala>

相关内容

  • 没有找到相关文章

最新更新