我曾经认为rdd.take(1)
和rdd.first()
完全相同。然而,在我的同事向我指出Spark's officiation documentation on RDD后,我开始怀疑这是否真的如此:
first():返回此RDD中的第一个元素。
take(num):获取RDD的前几个数字元素。 它首先扫描一个分区,然后使用该分区的结果来估计满足限制所需的额外分区数。
我的问题是:
first()
的基础实施是否与take(1)
相同?rdd1
和rdd2
是由同一个csv构建的,我可以放心地假设rdd1.take(1)
和rdd2.first()
将始终返回相同的内容结果,即csv的第一行?如果rdd1
和rdd2
的分区方式不同,该怎么办? 答案 0 :(得分:14)
Infact first
是根据take
实现的。
以下内容来自火花的RDD.scala来源。 first
调用take(1)
并返回第一个元素(如果找到)。
def first(): T = withScope {
take(1) match {
case Array(t) => t
case _ => throw new UnsupportedOperationException("empty collection")
}
}
take(num)
尝试从RDD的第0个分区开始获取num个元素(如果考虑基于0的索引)。所以take(1)和first的行为是相同的。
即使是spark programming guide也证实了这一点。
关于你的第二个问题:当你说区别不同时,这取决于你的意思。如果您使用或不使用numPartitions调用sc.textFile("/path/to/file")
,则无关紧要,因为第0个分区将始终为第0个分区。是的,你可以假设他们将拥有相同的第一个元素。
编辑:RDD中的分区是有序的,CSV中的物理第一行将在RDD的第0个分区中结束。并且take(1)
和first
都将返回第0个分区的第一行。
答案 1 :(得分:5)
两者都不相同。
rdd.first()
将返回此RDD中的第一个元素
而rdd.take(1)
将返回一个只有第一个元素的数组。
Ans:在实现方面,first()在内部调用take(1)并返回第一个且只返回take(1)返回的数组元素。取自org.apache.spark.rdd.RDD类
/**
* Return the first element in this RDD.
*/
def first(): T = withScope {
take(1) match {
case Array(t) => t
case _ => throw new UnsupportedOperationException("empty collection")
}
}
答案:是的,您可以认为,分区不会改变读取输入的顺序。
答案 2 :(得分:0)
因此,似乎两者是相同的,但我们确实存在差异。
1。当我们从文件中读取数据时,默认情况下它是RDD,并且RDD具有first()
和take()
属性。
2. first()
属性返回行类型对象,而take()
属性返回列表类型。
但是
使用.toDF()
将RDD转换为DataFrame后,该DF上就没有first()
属性。
希望它可以进一步澄清这些概念。