下面的Scala代码有意义吗?

7vux5j2d  于 7个月前  发布在  Scala
关注(0)|答案(1)|浏览(95)

我有下一句

val students = students_df
  .select(col("name"))
  .distinct
  .map(_.getString(0))
  .collect
  .toSeq

我的问题是,收藏真的有意义吗?我已经理解了收集和Map是一种相同的功能。所以我想看看这是否正确以及为什么。
如果这不是最有效的工作方式。我应该如何修改代码?只是删除收集?
Thanks in advance

5hcedyr0

5hcedyr01#

你说:

val students = students_df
  .select(col("name"))
  .distinct
  .map(_.getString(0))
  .collect
  .toSeq

我已经理解了收集和Map是一种相同的功能。
这在本案中并不完全正确听起来你很困惑

  • RDD.collect()
def collect(): Array[T]

返回一个包含此RDD中所有元素的数组。

注意事项

只有在预期结果数组较小时才应使用此方法,因为所有数据都加载到驱动程序的内存中。
和另一个

  • RDD.collect(PartialFunction)
def collect[U](f: PartialFunction[T, U])(implicit arg0: ClassTag[U]): RDD[U]

通过应用f返回一个包含所有匹配值的RDD。
第一个方法收集所有你收集的数据并将其加载到内存中,第二个方法类似于应用filtermap
在作为示例提供的代码中,collectmap并不相同。你需要传递一个PartialFunction来执行类似于map的操作。这样

val students = students_df
  .select(col("name"))
  .distinct
  .map(_.getString(0))
  .collect {
    // the `if` here is for filtering and what I returned after 
    // the `=>` is the transformation
    case x if x == "" => "Empty" 
    // here I am getting the rest of rows and not applying any 
    // transformation. If you don't do that, all the values that
    // aren't caught by this partial function will be discarded 
    // like in the `filter` method
    case x => x 
  }
  .toSeq

然后你问
如果这不是最有效的工作方式。我应该如何修改代码?只是删除收集?
你的问题没有提供背景。这意味着不可能说你所做的是否是最有效的方法。

Spark By Examples是一个很好的博客,有很多文章展示了如何在不同情况下使用spark的示例和细节。其中一个帖子是Collect() – Retrieve data from Spark RDD/DataFrame

collect()

Spark collect()collectAsList()是action操作,用于将RDD/DataFrame/Dataset的所有元素(从所有节点)检索到驱动程序节点。我们应该在较小的数据集上使用collect(),通常在filter(),group(),count()等之后使用。检索较大的数据集会导致内存不足。
此外,如果查看API文档,您可以看到关于不要在大型数据集上使用该方法的相同警告

  • RDD.collect()
def collect(): Array[T]

返回一个包含此RDD中所有元素的数组。

注意:此方法仅适用于预期结果数组较小的情况,因为所有数据都加载到驱动程序内存中。

  • Dataset.collect()
def collect(): Array[T]

返回包含此Dataset中所有行的数组。
运行collect需要将所有数据移动到应用程序的驱动程序进程中,在非常大的数据集上这样做可能会使驱动程序进程崩溃,OutOfMemoryError
使用此方法时要小心。也许RDD.toLocalIterator会更好。

相关问题