对于初始问题中的混淆,我们深表歉意。以下是可重复示例的问题:
我有一个[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。
再次抱歉,谢谢
答案 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)