【问题标题】:Splitting .ttl or .nt file - Spark Scala拆分 .ttl 或 .nt 文件 - Spark Scala
【发布时间】:2019-03-14 23:15:22
【问题描述】:

我是 scala 新手,我需要逐行读取 ttl 文件并在特定分隔符上拆分并提取值以放入数据框中的相应列中。

< http://website/Jimmy_Carter> <http://web/name> "James Earl Carter, Jr."@ko .
< http://website/Jimmy_Car> <http://web/country> <http://website/United_States> .
< http://website/Jimmy_Car> <http://web/birthPlace> <http://web/Georgia_(US)> .

我想要这个输出

+-------------------------------+---------------------------+-----------------------------
|S                              |P                          |O                                                             |
+-------------------------------+---------------------------+-----------------------------

|http://website/Jimmy_Car       |http://web/name            |"James Earl Carter                                                       |
|http:///website/Jimmy_Car      |http://web/country         |http://web/country                   |
|http://website/Jimmy_Car       |http://web/birthPlace      |http://web/Georgia_(US)             |
|

我试过这段代码

case class T(S: Option[String], P: Option[String],O:Option[String])


 val triples = sc.textFile("triples_test.ttl").map(_.split(" |\\< |\\> |\\ . ")).map(p => 
  T(Try(p(0).toString()).toOption,Try(p(1).toString()).toOption,Try(p(2).toString()).toOption)).toDF()

我得到了这个结果

    +-------------------------------+---------------------------+-----------------------------
|S                              |P                          |O                                                             |
+-------------------------------+---------------------------+-----------------------------

|<http://website/Jimmy_Car       |<http://web/name            |"James                                                       |
|<http:///website/Jimmy_Car      |<http://web/country         |<http://web/country                   |
|<http://website/Jimmy_Car       |<http://web/birthPlace      |<http://web/Georgia_(US) 

为了删除每个三元组开头的分隔符“

 val triples = sc.textFile("triples_test.ttl").map(_.split(" |\\< |\\> |\\ . |<")).map(p => 
  T(Try(p(0).toString()).toOption,Try(p(1).toString()).toOption,Try(p(2).toString()).toOption)).toDF()

我得到了这个结果

    +-------------------------------+---------------------------+-----------------------------
|S                              |P                          |O                                                             |
+-------------------------------+---------------------------+-----------------------------

|                                |http://web/name            |                                                      |
|                                |http://web/country         |                   |
|                                |http://web/birthPlace      | 

我该如何解决这个问题

【问题讨论】:

  • 嗨@NTH 我将代码更改为Scala,以防您无法执行它!祝你好运
  • 你好@AlexandrosBiratsis,非常感谢!因为我是 scala 编程的初学者,我也没有使用 python。但我忘记了我的问题的一个细节。在数据框的第三列(O 列)中,我只需要以“http://web/”开头的数据。因此,根据示例,我不需要将包含“James Earl Carter”的文件的所有行都放在数据框中。
  • 那么您必须删除负责该操作的正则表达式部分:) 您只需要稍微更改 url_regex 即可。试一试你会需要它们,而且是非常强大的工具...
  • @AlexandrosBiratsis 不,我没有删除它,因为我需要它,但我添加了这行代码 "val DF = dfA.filter($"Object".contains("http://web/ “))”。非常感谢:)
  • 那很好:)

标签: apache-spark split semantic-web


【解决方案1】:

如果不清楚如何用 Spark 中的内置正则表达式功能替换您的代码,请在下面找到答案。尽管在使用这种方法之前,您需要确保您了解正则表达式的工作原理。

val df = Seq(
        ("< http://website/Jimmy_Carter>", "<http://web/name>", "\"James Earl Carter, Jr.\"@ko .\""),
        ("< http://website/Jimmy_Car>", "<http://web/country>", "<http://website/United_States> ."),
        ("< http://website/Jimmy_Car>", "<http://web/birthPlace>", "<http://web/Georgia_(US)> .")
    ).toDF("S", "P", "O")

val url_regex = """^(?:"|<{1}\s?)(.*)(?:>(?:\s\.)?|,\s.*)$"""
val dfA = df.withColumn("S", regexp_extract($"S", url_regex, 1))
            .withColumn("P", regexp_extract($"P", url_regex, 1))
            .withColumn("O", regexp_extract($"O", url_regex, 1))

这将输出:

+---------------------------+---------------------+----------------------------+
|S                          |P                    |O                           |
+---------------------------+---------------------+----------------------------+
|http://website/Jimmy_Carter|http://web/name      |James Earl Carter           |
|http://website/Jimmy_Car   |http://web/country   |http://website/United_States|
|http://website/Jimmy_Car   |http://web/birthPlace|http://web/Georgia_(US)     |
+---------------------------+---------------------+----------------------------+

即使这不是帖子的主题,也只是稍微解释一下正则表达式的工作原理。

  1. (?:"|&lt;{1}\s?) 识别以 "&lt;&lt; 开头的行
  2. (.*)将匹配内容提取到第一组
  3. (?:&gt;(?:\s\.)?|,\s.*) 识别以 &gt;&gt; .,\s.* 结尾的行,用于 James Earl 案例

【讨论】:

    【解决方案2】:

    你不能像这样读取 Turtle 文件。另外,正则表达式是阅读 N-Triples 的一种非常幼稚的方式。不要重新发明轮子并使用https://github.com/banana-rdf/banana-rdf

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多