从spark数据帧中的字符串列中提取单词

时间:2017-12-26 17:18:57

标签: regex scala apache-spark

我在spark数据框中有一个包含文本的列。

我想提取所有以特殊字符'@'开头的单词,并且我在该文本列的每一行使用regexp_extract。如果文本包含以'@'开头的多个单词,则只返回第一个单词。

我正在寻找提取符合我的模式火花的多个单词。

data_frame.withColumn("Names", regexp_extract($"text","(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9_]+)",1).show

示例输入:@always_nidhi @YouTube no i dnt understand bt i loved the music nd their dance awesome all the song of this mve is rocking

示例输出:@always_nidhi,@YouTube

3 个答案:

答案 0 :(得分:5)

您可以在spark中创建一个udf函数,如下所示:

import java.util.regex.Pattern
import org.apache.spark.sql.functions.udf
import org.apache.spark.sql.functions.lit

def regexp_extractAll = udf((job: String, exp: String, groupIdx: Int) => {
      println("the column value is" + job.toString())
      val pattern = Pattern.compile(exp.toString)
      val m = pattern.matcher(job.toString)
      var result = Seq[String]()
      while (m.find) {
        val temp = 
        result =result:+m.group(groupIdx)
      }
      result.mkString(",")
    })

然后按如下方式调用udf:

data_frame.withColumn("Names", regexp_extractAll(new Column("text"), lit("@\\w+"), lit(0))).show()

上面给出的输出如下:

+--------------------+
|               Names|
+--------------------+
|@always_nidhi,@Yo...|
+--------------------+

我根据您在问题中发布的输出使用了正则表达式。您可以对其进行修改以满足您的需求。

答案 1 :(得分:1)

您可以使用java RegEx来提取这些单词。以下是工作代码。

val sparkConf = new SparkConf().setAppName("myapp").setMaster("local[*]")
val sc = new SparkContext(sparkConf)

val sqlContext = new org.apache.spark.sql.SQLContext(sc)
import sqlContext.implicits._
import org.apache.spark.sql.functions.{col, udf}
import java.util.regex.Pattern

//User Defined function to extract
def toExtract(str: String) = {      
  val pattern = Pattern.compile("@\\w+")
  val tmplst = scala.collection.mutable.ListBuffer.empty[String]
  val matcher = pattern.matcher(str)
  while (matcher.find()) {
    tmplst += matcher.group()
  }
  tmplst.mkString(",")
}

val Extract = udf(toExtract _)
val values = List("@always_nidhi @YouTube no i dnt understand bt i loved the music nd their dance awesome all the song of this mve is rocking")
val df = sc.parallelize(values).toDF("words")
df.select(Extract(col("words"))).show()
  

输出

+--------------------+
|          UDF(words)|
+--------------------+
|@always_nidhi,@Yo...|
+--------------------+

答案 2 :(得分:0)

我接受了Amit Kumar的建议并创建了一个UDF然后在spark sql中运行它:

从数据框

中选择单词(状态)作为人

“Words”是我的UDF,状态是我的数据框列。