我使用以下代碼:
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 所做的事情背后的邏輯。根據 spark 檔案 Select 回傳一個新的資料框。那么為什么它仍然能夠使用父資料框中的男性列。
uj5u.com熱心網友回復:
這是由 Spark 生成的 DAG 引起的。一些運算子(或transformers)是延遲執行的,因此它們為 Spark 優化 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]
uj5u.com熱心網友回復:
添加到@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子句)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/365211.html
標籤:数据框 阿帕奇火花 火花 apache-spark-sql
