【问题标题】:is pyspark dataframe when passed as argument, passed as reference or value?当作为参数传递,作为引用或值传递时,pyspark 数据帧是什么?
【发布时间】:2021-11-21 12:21:33
【问题描述】:

假设我有这个代码:

def func1():
    # some code to create a dataframe df
    df.persist(StorageLevel.MEMORY_AND_DISK)
    return df.repartition("col1", "col2")

def func2(df: Dataframe):
    df = (df.select("col1", "col2").groupby("col1").count().withColumnRenamed("count", "count_col1"))
    return df

所以在 func2 中,当我传递变量“df”时,它是通过引用传递还是通过值传递?我在func1中应用的repartition(),在将func2中的df用于groupBy时应该有助于提高性能吗? 类似地,如果我在 func1 中应用 persist(),那么它将正确保存在内存中,然后当我在 func2() 中引用 df 时,它将从它在 func1() 中仅保存一次的同一位置引用.对吗?

谢谢!

【问题讨论】:

    标签: performance pyspark parameter-passing pass-by-reference partitioning


    【解决方案1】:

    这里有两个方面:

    1. Pyton 变量 df 是作为值传递还是作为引用传递?
    2. df 引用的数据是如何传递的?

    对于第一个问题,有一些可用的答案,例如this one。但这是一个关于 Python 的问题,如果我们想知道 Spark 如何处理数据帧中的数据,这并不重要。

    要回答第二个问题,我们应该考虑df 的真正含义。 df 不包含实际数据,甚至不是对它的直接引用。相反,所有Spark transformations记录在该对象的执行计划中,当最终调用像savecountcollect 这样的操作时,Spark 会执行(在一些optimizations 之后)这个计划。这是 Spark 的执行器第一次实际移动任何数据。

    要检查执行计划,您可以调用DataFrame.explain。如果你运行这个函数,你会注意到——无论你的 Spark 逻辑多么复杂——它都会立即返回并打印出执行计划。这种快速响应的原因是没有执行实际的数据操作 - 直到您运行 Spark 操作。

    TL;DR:传递 Python 变量永远不会移动数据框中的任何数据。您最后一个问题的答案是

    【讨论】:

      【解决方案2】:

      在 Python 中,如果我们想了解参数是作为值传递还是作为引用传递,我们需要了解该参数是可变的还是不可变的。

      • 可变对象是在初始化后可以更改其值的对象(如列表、字典、集合)。它们是通过引用调用的。
      • 不可变对象是初始化后值不能改变的对象(如int、string、tuple、类对象)。为了改变它们的值,我们需要重新初始化它们。它们是按值调用的。

      PySpark 数据帧属于类对象类别并且是不可变的,因此按值调用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-11
        • 2023-03-23
        • 1970-01-01
        相关资源
        最近更新 更多