如何将已排序的RDD拆分为n个部分并从每个部分获取第一个元素?
问题描述:
我试图从排序的RDD [字符串]中提取一些元素。我尝试使用“zipWithIndex”并将剩余的RDD过滤为零。如何将已排序的RDD拆分为n个部分并从每个部分获取第一个元素?
val expectedSize = 165
val n = rddOfStrings.count/expectedSize
val resultArray = rddOfStrings.sortBy(x => x).zipWithIndex.filter(x => x._2 % n == 0).map(_._1).collect
这里的问题是“n”不总是整数。如果它是double,则resultArray的大小不会等于expectedSize(生成+1或-1)。如何使它返回相同大小的集合?
P.S.我通过向所有执行者传递集合对象来尝试spark累加器。由于非常大的数据集失败。
答
的165份不能等于,真的 - 他们中的一些会比其他假设总大小不是165
乘法要获得这些零件“尽可能均匀分布尽可能”你可以使用一个非舍n
,创建一个n, 2n, 3n, ...
流,然后在圆该流的每个元素让你后的元素的索引,然后使用contains
过滤RDD:
val expectedSize = 165
val n: Double = rddOfStrings.count.toDouble/expectedSize
val indices = Stream.iterate(0D)(x => x + n)
.map(math.round)
.take(expectedSize)
.toList
val resultArray = rddOfStrings.sortBy(x => x)
.zipWithIndex
.filter(x => indices.contains(x._2))
.map(_._1)
.collect
+0
完美!就像我想要的一样... – sen
是什么你的目标在这里?这只是为了从你的数据集中得到一个样本,spark实际上有一个你可以使用的样本方法。 – puhlen
我想将rdd(排序)分成165个相等部分,并从每个部分取第一个(头部)元素。 – sen