在另一个数据帧的转换中创建/访问数据帧

时间:2017-09-01 21:42:05

标签: scala apache-spark dataframe apache-spark-sql

我正在改造一些现有代码以使用Spark。我有多个数据框,包含不同的数据集。 在转换我的主数据帧(或我的主数据集)时,我需要使用其他数据帧中的数据来完成转换。我还有一种情况(至少在当前结构中),我需要在另一个数据帧的转换函数中创建新的数据帧。

我正在尝试确定以下内容:

  1. 我可以访问另一个数据框的转换函数内的数据框吗?
  2. 可以在数据帧的转换函数内的执行器上创建数据框吗?
  3. 关于如何处理这种情况的指示将非常有帮助。

1 个答案:

答案 0 :(得分:5)

这两个问题的答案是

DataFrames是分布式集合的驱动程序端抽象。它们不能在任何执行程序端转换中使用,创建或引用。

<强>为什么? DataFrames(如RDD和数据集)只能在活动SparkSession的上下文中使用 - 没有它,DataFrame不能指向&#34;指向&#34;到活动执行器上的分区; SparkSession应该被认为是一个真实的连接&#34;到执行者集群。

现在,如果你尝试在另一个转换中使用DataFrame,那么DataFrame必须在驱动程序端序列化,发送给执行程序,然后反序列化SparkSession - 那个&#34;连接&#34;是从驱动程序到执行程序,而不是我们现在正在运行的新执行程序。

那你应该怎么做? 您有一些选项可以在另一个中引用一个DataFrame的数据,而选择正确的一个主要取决于必须进行混洗(或 - 在执行程序之间传输)的数据量:

  1. 收集其中一个DataFrame(如果您可以保证它很小!),然后使用生成的本地集合(直接或使用spark.broadcast)在任何转型中。

  2. 在一些常见字段上加入两个DataFrame。这是一种非常常见的解决方案,因为在转换另一个DataFrame数据时使用一个DataFrame数据的逻辑通常与某种&#34; lookup&#34;根据列的某个子集获得正确的值。这个用例很自然地转换为JOIN操作

  3. 使用集合运算符,如exceptintersectunion,如果它们提供您之后的逻辑运算。