火花选择列返回参考的旧数据框

0

的问题

我使用了下列代码:

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|
+---------+-------+

我想要了解背后的逻辑什么样的火花在做什么。 因为每次的火花文件选择返回一个新的数据框. 那么为什么它仍然能够使用男列从父数据框.

2

最好的答案

3

这是由DAG产生火花。 一些运营商(或者 transformers)是延迟执行,使他们铺平道路火花优化DAG。

在这个例子中,有两个主要步骤: select (或 project 在SQL的术语)第一, 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]
2021-11-24 01:29:03
1

加@chenzhongpu's答案,请注意,如果界定一个临时看上你的 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 条款)。

2021-11-24 14:25:52

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................