使用以下代码我得到了非常奇怪的结果。 我只想获取分区数据并迭代每个数据X次。
我在这里为每个分区调用我的函数:
val myRDDResult = myRDD.mapPartitionsWithIndex( myFunction(_, _, limit), preservesPartitioning = true)
功能是:
private def myFunction (partitionIndex: Long,
partitionData: Iterator[Array[(LabeledPoint,Int,Int)]]), limit: Int): Iterator[String] = {
var newData = ArrayBuffer[String]()
if (partitionData.nonEmpty){
val partDataMap = partitionData.next.map{ case (lp, _, neighId) => (lp, neighId) }.toMap
var newString:String = ""
for {
(k1,_) <- partDataMap
i <- 0 to limit
_ = {
// ... some code to generate the content for `newString`
newData.+=(newString)
}
}yield ()
}
newData.iterator
}
以下是获得的一些值:
partitionData limit newData newData_expected
1640 250 411138 410000 (1640*250)
16256 27 288820 438912
我不知道我是否误解了我的代码的一些概念。
我也尝试更改for
这个想法的部分:partDataMap.map{elem=> for (i <- 0 to limit){....}}
有什么建议吗?
答案 0 :(得分:2)
首先,抱歉,因为我对你的问题进行了投票/上调(点击错误),因为我没有在10分钟内取消它,所以保持了它的投票。
关于你的代码,我认为你的预期结果很糟糕,因为我使用了与你相同的代码,简化了一点,而不是接收 410000 元素,我得到 411640 < / em>的。也许我复制了一些不正确的东西或忽略了一些东西,但给出411640的代码看起来像:
val limit = 250
val partitionData: Iterator[Array[Int]] = Seq((1 to 1640).toArray).toIterator
var newData = ArrayBuffer[String]()
if (partitionData.nonEmpty){
val partDataMap = partitionData.next.map{ nr => nr.toString }
for {
value <- partDataMap
i <- 0 to limit
_ = {
newData.+=(s"${value}_${i}")
}
} yield ()
}
println(s"new buffer=${newData}")
println(s"Buffer size = ${newData.size}")
现在回答您关于为什么mapWithPartitions
结果与您的期望不同的问题。 IMO,因为您从Array
转换为Map
。如果在您的阵列中有重复键,它将只计数一次。它可以解释为什么在这两种情况下(如果我们将411640视为正确的预期数字),您会得到低于预期的结果。为确保您可以将partDataMap.size
与partitionData.next.size
进行比较。