【问题标题】:spark select column returns reference of old dataframe火花选择列返回旧数据框的引用
【发布时间】:2022-01-02 09:14:10
【问题描述】:

我使用以下代码:

random = [("ABC",xx, 1), 
          ("DEF",yy,1), 
          ("GHI",zz, 0) 
         ]
randomColumns = ["name","id", "male"]
randomDF = spark.createDataFrame(data=random, schema = randomColumns)
test_df = randomDF.select("name", "id")
test_df.filter(f.col("male") == '1').show()

从上面的代码中,我预计它会导致错误,因为对于 test_df,我没有从原始数据框中选择男性列。令人惊讶的是,上面的查询运行良好,没有任何错误,并输出以下内容:

+---------+-------+
|name     |     id|
+---------+-------+
|      abc|     xx|
|      def|     yy|
+---------+-------+

我想了解 spark 所做工作背后的逻辑。根据火花文档 Select 返回一个新的数据框。那为什么它仍然可以使用父数据框中的男性列。

【问题讨论】:

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


    【解决方案1】:

    这是由 Spark 生成的 DAG 引起的。一些运算符(或transformers)是惰性执行的,因此它们为 Spark 优化 DAG 铺平了道路。

    在这个例子中,主要有两个步骤:首先是select(或者用SQL的术语来说是project),然后是filter。但实际上执行的时候,是先filter,然后是select ,因为它更有效。

    你可以通过explain()方法验证这个结论:

    test_df.filter(f.col("flag") == '1').explain()
    

    它会输出:

    == Physical Plan ==
    *(1) Project [dept_name#0, dept_id#1L]
    +- *(1) Filter (isnotnull(flag#2L) AND (flag#2L = 1))
       +- *(1) Scan ExistingRDD[dept_name#0,dept_id#1L,flag#2L]
    

    【讨论】:

      【解决方案2】:

      添加到@chenzhongpu 的答案,请注意,如果您在test_df 之上定义临时视图,查询将失败:

      test_df.createOrReplaceTempView("test_df")
      spark.sql("select * from test_df where flag = 1").show()
      _Traceback (most recent call last): ...
      :
      pyspark.sql.utils.AnalysisException: u"cannot resolve '`flag`' given input columns: [test_df.dept, test_df.id]; line 1 pos 24;
      'Project [*]
       +- 'Filter ('flag = 1)
         +- SubqueryAlias `test_df`
            +- Project [dept#0, id#2L]
               +- LogicalRDD [dept#0, flag#1L, id#2L], false
       _
      

      ...因为select(执行计划中的=Project 节点)将优先于过滤器(通过where 子句尝试)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-04
        • 1970-01-01
        • 2020-03-20
        • 2018-09-26
        • 2015-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多