Spark:正确的方法来删除RDD的最后一个元素[String]

时间:2018-05-18 23:10:23

标签: scala performance apache-spark

我正在尝试删除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的最后一个元素,并对其进行过滤以使所有元素减去最后一个元素。

这很好用,但还有更好的方法吗?

2 个答案:

答案 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排序或将其保存到文件中。