2016-03-08 11 views
18

voglio filtrare un Pyspark dataframe con un IN clausola di SQL-like, come inFiltrare un Pyspark dataframe con SQL-like IN clausola

sc = SparkContext() 
sqlc = SQLContext(sc) 
df = sqlc.sql('SELECT * from my_df WHERE field1 IN a') 

dove a è la tupla (1, 2, 3). Sto ottenendo questo errore:

java.lang.RuntimeException: [1.67] failure: ``('' expected but identifier a found

che è fondamentalmente dicendo che si aspettava qualcosa di simile '(1, 2, 3)' invece di una. Il problema è che non riesco a scrivere manualmente i valori in a come viene estratto da un altro lavoro.

Come faccio a filtrare in questo caso?

risposta

34

Stringa passata a SQLContext valutata nell'ambito dell'ambito SQL. Non cattura la chiusura. Se si vuole passare una variabile si dovrà farlo in modo esplicito utilizzando la formattazione stringa:

df = sc.parallelize([(1, "foo"), (2, "x"), (3, "bar")]).toDF(("k", "v")) 
df.registerTempTable("df") 
sqlContext.sql("SELECT * FROM df WHERE v IN {0}".format(("foo", "bar"))).count() 
## 2 

Ovviamente questo non è qualcosa che si usa in un ambiente SQL "reale" per motivi di sicurezza, ma non dovrebbe importa qui.

In pratica DataFrame DSL è una molta scelta quando si desidera creare query dinamiche:

from pyspark.sql.functions import col 

df.where(col("v").isin({"foo", "bar"})).count() 
## 2 

E 'facile da costruire e comporre e gestisce tutti i dettagli dell'annuncio HiveQL/Spark SQL per voi.

+0

Per il secondo metodo, è possibile ottenere lo stesso facendo df.where (df.v.isin ({"foo", "bar"})). count() –

+3

Puoi, ma personalmente non mi piace questo approccio. Con 'col' posso facilmente disaccoppiare l'espressione SQL e un particolare oggetto' DataFrame'. Ad esempio, puoi tenere un dizionario di espressioni utili e selezionarle quando necessario. Con l'oggetto DF esplicito devi metterlo in una funzione e non lo compone bene. – zero323

12

ribadendo quanto @ zero323 ha già detto: siamo in grado di fare la stessa cosa con una lista così (non solo set) come qui di seguito

from pyspark.sql.functions import col 

df.where(col("v").isin(["foo", "bar"])).count() 
Problemi correlati