如何用RDD类型的值[String,Int]替换[String]的RDD类型

时间:2016-04-12 08:15:26

标签: scala apache-spark rdd

对于初始问题中的混淆,我们深表歉意。以下是可重复示例的问题:

我有一个[String]的rdd,我有一个[String, Long]的rdd。我希望[Long]的rdd基于第一个String和第一个String的匹配。例如:

//Create RDD
val textFile = sc.parallelize(Array("Spark can also be used for compute intensive tasks",
      "This code estimates pi by throwing darts at a circle"))
// tokenize, result: RDD[(String)]
val words = textFile.flatMap(line => line.split(" "))
// create index of distinct words, result:  RDD[(String,Long)]
val indexWords = words.distinct().zipWithIndex()

因此,我希望在"Spark can also be used for compute intensive tasks"中有一个带有单词索引而不是单词的RDD。

再次抱歉,谢谢

2 个答案:

答案 0 :(得分:0)

如果我理解正确,您会对Spark can also be used for compute intensive tasks中出现的作品索引感兴趣。

如果是这样 - 这里有两个版本具有相同的输出但性能特征不同:

val lookupWords: Seq[String] = "Spark can also be used for compute intensive tasks".split(" ")

// option 1 - use join:
val lookupWordsRdd: RDD[(String, String)] = sc.parallelize(lookupWords).keyBy(w => w)
val result1: RDD[Long] = indexWords.join(lookupWordsRdd).map { case (key, (index, _)) => index }

// option 2 - assuming list of lookup words is short, you can use a non-distributed version of it
val result2: RDD[Long] = indexWords.collect { case (key, index) if lookupWords.contains(key) => index }

第一个选项创建第二个RDD,其中包含我们感兴趣的索引,使用keyBy将其转换为PairRDD(键==值!),join您的indexWords RDD然后映射以获取索引。

第二个选项只应在已知“有趣词汇”列表不太大的情况下使用 - 所以我们可以将其保存为列表(而不是RDD),并让Spark序列化它发送给每个要使用的任务的工人。然后我们使用collect(f: PartialFunction[T, U])来应用这个部分函数来立即获得“过滤器”和“地图” - 如果列表中存在单词,我们只返回一个值,如果是,则返回索引。 / p>

答案 1 :(得分:0)

我收到了SPARK-5063的错误并给了this answer,我找到了解决问题的方法:

//broadcast `indexWords`
val bcIndexWords = sc.broadcast(indexWords.collectAsMap)
// select `value` of `indexWords` given `key`
val result = textFile.map{arr => arr.split(" ").map(elem => bcIndexWords.value(elem))}
result.first()
res373: Array[Long] = Array(3, 7, 14, 6, 17, 15, 0, 12)