Scintilla selezionare la colonna restituisce riferimento del vecchio dataframe

0

Domanda

Io uso il seguente codice:

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()

Il codice di cui sopra, mi aspetto che si tradurrà in un errore, perché per la test_df io non selezionare il maschio colonna originale dataframe. Sorprendentemente la query di cui sopra, scorre bene senza errori e uscite il seguente:

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

Voglio capire la logica che sta dietro a ciò scintilla sta facendo. Come per la scintilla documentazione Select restituisce un nuovo dataframe. Allora perché è ancora in grado di utilizzare il maschio colonna dal genitore dataframe.

2

Migliore risposta

3

Questo è causato da DAG generato da Spark. Alcuni operatori (o transformers) è pigro, eseguito, in modo che spianare la strada per una Scintilla per ottimizzare il DAG.

In questo esempio, ci sono due fasi principali: select (o project in SQL il gergo) prima, e filter più tardi. Ma in realtà, durante l'esecuzione, filter prima, e poi selectperché è più efficiente.

È possibile verificare questa conclusione da explain() metodo:

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

Il risultato sarà:

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

L'aggiunta di @chenzhongpu 's risposta, si prega di notare che se si definisce una temp vista sulla parte superiore del vostro test_dfla query ha esito negativo:

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
 _

...perché un select (=Project nodo del piano di esecuzione) sta andando a precedere il filtro (tentato la via where clausola).

2021-11-24 14:25:52

In altre lingue

Questa pagina è in altre lingue

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