【问题标题】:Splitting an RDD[String] type text to RDD[String] type words (Scala, Apache Spark)将 RDD[String] 类型的文本拆分为 RDD[String] 类型的单词(Scala、Apache Spark)
【发布时间】:2017-10-10 22:59:19
【问题描述】:

我正在使用 Apache Spark 和 Scala,并且有一个文本中的行的文本 RDD[String]。我想将其拆分为单词(就像在每个空格处拆分一样)并取出另一个由单独单词组成的 RDD[String]。

我尝试在每个空格处拆分文本,但不知道如何将 Array[String] 转换为 RDD[String]。

val lines = sc.textFile(filename)

val words = lines.map(line => line.split('_'))

我也试过

val words = lines.flatMap(line => line.split('_')).collect()

但我仍然得到一个 Array[String]

作为一种不同的方法,我尝试获取空间的索引,然后在这些索引处拆分行,但每次必须使用具有不同数量和空间位置的单独行并获得RDD[Array[Int]] 中的 Array[Int]。

val spaces = lines.map(line => line.zipWithIndex.filter(_._1 == ' ').map(_._2))

谁能帮忙?

【问题讨论】:

  • 你得到了一个数组,因为你调用了collect(),它将RDD中的数据收集到一个本地数组中。只需使用lines.flatMap(line => line.split('_'))
  • 鉴于 Spark 的 DataFrames/Datasets 的新世纪,您为什么要使用 RDD?我相信您会更喜欢使用 Spark。

标签: arrays string scala apache-spark rdd


【解决方案1】:

当我们从sparkContext.textFile 读取时,我们已经有了RDD[String]
在你的情况下

val lines = sc.textFile(filename)

你已经有RDD[String]
还有map 函数

val words = lines.map(line => line.split('_'))

RDD[String]String 拆分为Array,从而将其转换为RDD[Array[String]]
你还有一个RDD
现在如果你正在寻找RDD[RDD[String]],你可以这样做

val words = lines.map(line => sparkContext.parallelize(line.split('_')))

并且flatMap 将每个拆分的单词输出到单独的行中

val words = lines.flatMap(line => line.split('_'))

应该是RDD[String]


collect()RDD[String] 变成了 Array[String]

【讨论】:

    【解决方案2】:

    如果您的 map 操作返回一些集合但您希望将结果展平为所有单个元素的 rdd,请使用 flatmap

    val words = lines.flatMap(line => line.split('_'))
    

    会将行转换为RDD[String],其中 rdd 中的每个字符串都是一个单独的单词。 split 返回一个包含所有单词的数组,因为它在 flatmap 中,结果被“展平”到各个元素中。

    你已经有了这个,但你在最后添加了一个collect()collect() 从 RDD 中获取所有数据并将其加载到集群上的 Array 中。换句话说,它将一个 RDD 变成了一个数组。如果你想让事情留在 RDD 中,你需要做的就是不要打电话给collect()

    【讨论】:

      【解决方案3】:
      val lines = sc.parallelize(List("there are", "some words"), 2)
      
      val words1 = lines.map(l => l.split(" ")) // => words1: Rdd[Array[String]] => word1.collect => Array(Array(there, are), Array(some, words))
      
      val words2 = lines.flatMap(_.split(" ") // words2: Rdd[String] => words2.collect => Array(there, are, some, words)
      

      Spark 操作有两种类型:转换和操作。 转换是惰性求值的,而操作会将最终结果返回给驱动程序或将其写入文件系统。 因此,在处理大型数据集时应该考虑一下。

      【讨论】:

        猜你喜欢
        • 2020-08-17
        • 2017-01-29
        • 2021-09-28
        • 1970-01-01
        • 2019-09-19
        • 1970-01-01
        • 2021-10-16
        • 2017-02-17
        • 1970-01-01
        相关资源
        最近更新 更多