在另一个数据框的转换中创建/访问数据框
Posted
技术标签:
【中文标题】在另一个数据框的转换中创建/访问数据框【英文标题】:Creating/accessing dataframe inside the transformation of another dataframe 【发布时间】:2017-09-01 21:42:05 【问题描述】:我正在改造一些现有代码以使用 Spark。我有多个包含不同数据集的数据框。 在转换我的主数据框(或我的主数据集)时,我需要使用来自其他数据框的数据来完成转换。我还有一种情况(至少在当前结构中),我需要在另一个数据帧的转换函数中创建新的数据帧。
我正在尝试确定以下内容:
-
我可以在另一个数据框的转换函数中访问一个数据框吗?
能否在数据帧的转换函数内的执行器上创建数据帧?
关于如何处理这种情况的指针将非常有帮助。
【问题讨论】:
您希望从辅助/辅助数据帧中获取什么样的数据;它是键值,聚合等吗?您正在谈论对您的主要 DF 进行什么样的转换;分组 + 聚合,使用 RDD 上的 map 函数等? 【参考方案1】:这两个问题的答案都是否:
DataFrames 是分布式集合的驱动端抽象。它们不能在任何执行器端转换中使用、创建或引用。
为什么?
DataFrames(如 RDD 和 Datasets)只能在活动 SparkSession
的上下文中使用 - 没有它,DataFrame 无法“指向”活动执行器上的分区; SparkSession
应该被认为是与执行器集群的实时“连接”。
现在,如果您尝试在另一个转换中使用 DataFrame,则该 DataFrame 必须在驱动程序端进行序列化,发送到执行程序,然后反序列化时间>那里。但是这个反序列化的实例(在一个单独的 JVM 中)必然会丢失它的 SparkSession
——“连接”是从驱动程序到执行程序,而不是来自我们现在正在运行的这个新执行程序。
那么你应该怎么做? 您有几个选项可以在另一个 DataFrame 中引用一个 DataFrame 的 data,而选择正确的选项主要取决于必须改组(或 - 在执行程序之间传输)的数据量:
收集其中一个 DataFrame(如果你能保证它很小!),然后在任何转换中使用生成的本地集合(直接或使用 spark.broadcast
)。
加入在一些公共字段上的两个 DataFrame。这是一个非常常见的解决方案,因为在转换另一个 DataFrame 数据时使用一个 DataFrame 数据的逻辑通常与基于某些列子集对正确值的某种“查找”有关。这个用例很自然地转化为 JOIN 操作
使用集合运算符,例如 except
、intersect
和 union
,如果它们提供您所追求的逻辑运算。
【讨论】:
好吧,我有一个倾向,答案是否定的,但你的解释很有帮助。对于某些数据集,连接对我有用。我不确定我是否了解如何在执行程序中进行收集并在本地使用它。收集的结果不会导致本地驱动程序上的数据集吗? Right -collect
会产生驱动端的本地结果;如果您随后尝试在转换中使用该结果,Spark 将序列化该集合并将其与使用它的函数一起发送到每个执行器;这将在每个任务 中完成,所以如果这个集合不是很小,您可以使用广播来确保每个执行器 只发送一次。仅当该集合足够小以驻留在驱动程序的内存中时,这两个选项才相关。
collect
+ broadcast
在两个数据集没有直接关系并且您需要在另一个数据集中找到关系的情况下很有帮助,即直接连接或范围连接可能不会工作。但我仍然想弄清楚的是如何处理第二个数据集不适合内存的情况。如何处理两者之间没有直接关系但希望在 spark 上分配处理的数据集?
即使没有“直接”关系 - 也存在 some 关系:您可以使用一些逻辑将一个或多个记录从一个 DataFrame 匹配到另一个 DataFrame 中的每个记录, 对?通常,此逻辑可以表示为对各个 DataFrame 的一系列转换并在它们之间进行连接。如果您有无法找到该翻译的特定要求 - 请随时发布单独的问题。
@BdEngineer 抱歉,这不是这个平台的工作方式...如果您可以将您的问题描述为一个新问题,您将更有机会获得有用的答案。以上是关于在另一个数据框的转换中创建/访问数据框的主要内容,如果未能解决你的问题,请参考以下文章
从列表中创建一个 pyspark 数据框列,其中列表的长度与数据框的行数相同
如何在 Python 中创建具有两列作为元组或 Pandas 数据框的单个变量?