我有兩個場景與不同的結果:
場景1:
從pyspark.sql。功能導入*
#創建示例dataframes
df1 =火花。createDataFrame ([(1、2、3), (2、3、4)], [“a”、“b”、“c”))
df2 =火花。createDataFrame ([(1、5、6、7), (2, 8, 9, 10)], [“a”、“d”、“e”,“f”))
df3 =火花。createDataFrame ([(1、11、12), (2, 13、14)], [“a”、“g”、“h”))
#加入dataframes並選擇列
= df1基地。加入(df2,“a”,“左”)。加入(df3,“a”,“左”)。選擇(“a”、“b”、“e”,“g”)
#應用過濾器
最後= base.filter(坳(“c”) = = 1)
場景2:
從pyspark.sql。功能導入*
#創建示例dataframes
df1 =火花。createDataFrame ([(1、2、3), (2、3、4)], [“a”、“b”、“c”))
df2 =火花。createDataFrame ([(1、5、6、7), (2, 8, 9, 10)], [“a”、“d”、“e”,“f”))
df3 =火花。createDataFrame ([(1、11、12), (2, 13、14)], [“a”、“g”、“h”))
df4 = spark.createDataFrame (((1), (2)]、[a])
df5 =火花。createDataFrame ([(1,“x”), (2, y)], [“a”,“z”))
#加入dataframes
= df1基地。加入(df2,“a”,“左”)。加入(df3,“a”,“左”)。選擇(“a”、“b”、“e”,“g”)
base_join =基地。加入(df4,“a”)。加入(df5,“a”,“左”)。選擇(“a”、“b”)
#應用過濾器
最後= base_join .filter(坳(“c”) = = 1)
我第一個場景過濾器(坳(“c”) = = 1)將應用和dataframe稱為最後的創建,在場景2中,將失敗與錯誤”專欄“c”不存在“即使base_join df在第二個場景中與基地df第一沒有這一列。
有什麼區別,為什麼在物理計劃嗎?
@Direo Direo:
兩種情況的區別在於執行計劃所產生的火花。當火花優化並執行一個查詢,它生成一個具體的計劃,包括所有的操作需要執行產生最終結果。物理計劃通過一係列優化生成的邏輯計劃查詢,如謂詞下推,投影修剪,加入重新排序。
在第一個場景中,直接用於基礎dataframe過濾操作,它隻包含列“a”、“b”,“e”和“g”。因此,當火花產生的物理方案,它不包括“c”列,因為它不需要過濾的操作。
在第二個場景中,過濾操作應用於base_join dataframe,這是一個連接操作的結果,包括“a”、“b”,“e”和“g”列。然而,df1 dataframe,其中包含“c”列,也包括在連接操作。因此,當火花產生的物理方案,它包括“c”列在連接操作,即使它是不習慣在最後的過濾操作。
修複錯誤在第二個場景中,你可以添加一個投影操作
base_join刪除“c”列在應用過濾器之前操作:
base_join =基地。加入(df4,“a”)。加入(df5,“a”,“左”)。選擇(“a”、“b”、“e”,“g”) base_join_projected = base_join.drop (“c”)最終= base_join_projected.filter(坳(“c”) = = 1)
這將從物理刪除“c”列計劃,和過濾操作應正常工作。
@Direo Direo:
兩種情況的區別在於執行計劃所產生的火花。當火花優化並執行一個查詢,它生成一個具體的計劃,包括所有的操作需要執行產生最終結果。物理計劃通過一係列優化生成的邏輯計劃查詢,如謂詞下推,投影修剪,加入重新排序。
在第一個場景中,直接用於基礎dataframe過濾操作,它隻包含列“a”、“b”,“e”和“g”。因此,當火花產生的物理方案,它不包括“c”列,因為它不需要過濾的操作。
在第二個場景中,過濾操作應用於base_join dataframe,這是一個連接操作的結果,包括“a”、“b”,“e”和“g”列。然而,df1 dataframe,其中包含“c”列,也包括在連接操作。因此,當火花產生的物理方案,它包括“c”列在連接操作,即使它是不習慣在最後的過濾操作。
修複錯誤在第二個場景中,你可以添加一個投影操作
base_join刪除“c”列在應用過濾器之前操作:
base_join =基地。加入(df4,“a”)。加入(df5,“a”,“左”)。選擇(“a”、“b”、“e”,“g”) base_join_projected = base_join.drop (“c”)最終= base_join_projected.filter(坳(“c”) = = 1)
這將從物理刪除“c”列計劃,和過濾操作應正常工作。