当前位置: 首页 > 知识库问答 >
问题:

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

翁宜年
2023-03-14

我在spark dataframe中有一个包含文本的列。

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

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

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

样本输入:< code>@always_nidhi @YouTube不,我不明白,但我喜欢他们的音乐和舞蹈真棒这首mve的所有歌曲都很摇滚

示例输出:@always_nidhi,@YouTube

共有3个答案

龚奕
2023-03-14

在Spark 3.1中,可以使用< code>regexp_extract_all

使用您的输入进行测试:

import spark.implicits._
var df = Seq(
    ("@always_nidhi @YouTube no"),
    ("@always_nidhi"),
    ("no")
).toDF("text")

val col_re_list = expr("regexp_extract_all(text, '(?<=^|(?<=[^a-zA-Z0-9-_\\\\.]))@([A-Za-z]+[A-Za-z0-9_]+)', 0)")
df.withColumn("Names", array_join(col_re_list, ", ")).show(false)

// +-------------------------+-----------------------+
// |text                     |Names                  |
// +-------------------------+-----------------------+
// |@always_nidhi @YouTube no|@always_nidhi, @YouTube|
// |@always_nidhi            |@always_nidhi          |
// |no                       |                       |
// +-------------------------+-----------------------+
  • array_join被使用,因为您希望结果是字符串格式,而regexp_extract_all返回数组。
  • 如果在模式中使用\进行转义,则需要使用\\\而不是\,直到regexp_extract_all直接可用而无需exr
段兴为
2023-03-14

您可以使用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...|
+--------------------+
戚英逸
2023-03-14

您可以在 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...|
+--------------------+

根据你在问题中发布的输出,我使用了regex。你可以修改它来适应你的需要。

 类似资料:
  • 我有一个函数,它接受一个字符串参数,并对其进行“匹配”以确定返回值,如下所示- 编辑(完成功能):

  • 我的数据框中有一列包含JSON列表,但类型是字符串。我需要在此列上运行,因此首先需要将其转换为列表。我找不到太多关于这个用例的参考。 示例数据: 上面是数据的样子,字段是不固定的(索引0可能有JSON和一些字段,而索引1将有一些字段和一些其他字段)。列表中可以有更多嵌套的JSONs或一些额外的字段。我现在正在用这个- <code>“分解(拆分(regexp_replace(regexp_repla

  • 问题内容: 我有一个包含Json的字符串。看起来像这样: 我正在尝试保留“ img_url”。我已经安装了Json.NET,并且在这里发现了类似的问题。 例如这样的事情: 在我来说,我改变到,etc..no运气 现在这是我的代码: 在提取值之前,是否必须对字符串做一些事情?谢谢! 问题答案: 不是根对象的属性-它是对象的属性: 另外的选择:

  • 有几个关于字符串操作的问题,但我找不到一个可以让我做以下事情的答案-我认为应该很简单。。。 我有一个DataFrame,其中包括一个包含文件名和路径的列 下面生成一个代表性的示例数据帧: 我想以字符串的“文件名”部分结束。有大量的行,并且路径不是常量,因此我不能使用<code>str.replace 我可以像这样去掉最右边的. csv部分: 但是我无法使我读过的任何方法都能够删除字符串左侧的路径部

  • 问题内容: 我想从包含数字和字母的字符串中提取数字: 我想在这里获取号码或任何其他号码。 问题答案:

  • 我有火花2.2中的数据框,我想读取一个列值作为字符串。 当col1为空时,我想在col2中获取字符串值,并在那里追加我的逻辑。 问题是我总是得到作为。我如何将此值转换为以追加我的自定义字符串?