我正在尝试删除RDD [String]的最后一个元素。
到目前为止,我这样做了:
val n: Long = rdd.count()
val startIndex: Long = n - 1
val lastElem = rdd.zipWithIndex()
.filter{ case (_, index) => index >= startIndex }
.keys
.collect()
val newRdd = rdd.filter(x => !x.equalsIgnoreCase(lastElem(0))).cache()
即,获取rdd的最后一个元素,并对其进行过滤以使所有元素减去最后一个元素。
这很好用,但还有更好的方法吗?
答案 0 :(得分:0)
scala 中有init
个函数,它为您提供除集合中最后一个元素之外的所有元素。你可以利用那个
val newRdd = sc.parallelize(rdd.collect().toList.init)
这应该通过删除最后一个元素给你 new rdd,并且比你的方法更好,因为collect只使用一次。
并且rdd是分布式的,没有办法告诉哪一个是最后一个字符串而没有将它收集到一个节点。
此处我已将其收集到驱动程序节点。 您可以使用其他技术收集到一个执行程序并使用init
函数
答案 1 :(得分:0)
假设顺序定义明确(上游没有宽泛的转换,并且输入源保证元素的顺序定义明确),您当前的解决方案将尽其所能。
尤其应该避免不可扩展和整体无用(如果未正确定义RDD中的值顺序,则collected
Array
中的顺序值也未正确定义。){{1} }。
在使用之前,请务必了解限制。 Quoting the docs:
请注意,某些RDD(例如由groupBy()返回的RDD)不能保证分区中元素的顺序。因此,不能保证分配给每个元素的唯一ID,并且如果重新评估RDD甚至可能会更改。如果需要固定顺序来保证相同的索引分配,则应使用sortByKey()对RDD排序或将其保存到文件中。