DataFrame中包含子字符串的行数

时间:2018-06-28 08:49:38

标签: regex scala apache-spark

我尝试了此解决方案以测试子字符串中是否有字符串:

val reg = ".*\\[CS_RES\\].*".r
reg.findAllIn(my_DataFrame).length

但是它不起作用,因为我无法将findAllIn应用于数据框。

我尝试了第二种解决方案,将DataFrame转换为RDD

val rows: RDD[Row] = myDataFrame.rdd

val processedRDD = rows.map{

    str => 
         val patternReg = ".*\\[CS_RES\\].*".r
         val result = patternReg.findAllIn(str).length
         (str, result)
}

显示错误:

<console>:69: error: type mismatch;
 found   : org.apache.spark.sql.Row
 required: CharSequence
       val result = patternReg.findAllIn(str).length

在第一种解决方案中,我如何在DataFrame Scala上应用正则表达式来计算包含字符串number of the lines的{​​{1}} 还是有人对第二个解决方案有解决方案?

2 个答案:

答案 0 :(得分:2)

您可以使用regexp_extract函数对行进行过滤和计数。例如:

  import org.apache.spark.sql.SparkSession
  import org.apache.spark.sql.functions._

  private val session: SparkSession = ...

  import session.implicits._

  val myDataFrame = Seq(
    (1L, "abc"),
    (2L, "def"),
    (3L, "a[CS_RES]b"),
    (4L, "adg")
  ).toDF("id", "text")

  val resultRegex = myDataFrame.where(regexp_extract($"text", "\\[CS_RES\\]", 0).notEqual("")).count()

  println(resultRegex) // outputs 1

想法是:如果regexp_extract返回的第一组(i = 0)不是空字符串,则找到子字符串。调用count()会返回这些字符串的总数。

但是,如果您需要查找仅精确匹配的子字符串,则可以使用locate函数来简化解决方案:

  val resultLocate = myDataFrame.where(locate("[CS_RES]", $"text") > 0).count()

  println(resultLocate) // outputs 1

答案 1 :(得分:1)

import org.apache.spark.sql.functions.udf
val reg = ".*\\[CS_RES\\].*".r
val contains=udf((s:String)=>reg.findAllIn(s).length >0)

val cnt = df.select($"summary").filter(contains($"summary")).count()