2015-10-09 35 views
9

Come accennato in manyother locations sul Web, aggiungere una nuova colonna a un DataFrame esistente non è semplice. Sfortunatamente è importante avere questa funzionalità (anche se è inefficiente in un ambiente distribuito) specialmente quando si tenta di concatenare due DataFrame s usando unionAll.Aggiungere una colonna vuota per accendere DataFrame

Qual è la soluzione più elegante per aggiungere una colonna null a DataFrame per facilitare un unionAll?

La mia versione è questa:

from pyspark.sql.types import StringType 
from pyspark.sql.functions import UserDefinedFunction 
to_none = UserDefinedFunction(lambda x: None, StringType()) 
new_df = old_df.withColumn('new_column', to_none(df_old['any_col_from_old'])) 

risposta

15

Tutto ciò che serve qui è un letterale e cast:

from pyspark.sql.functions import lit 

new_df = old_df.withColumn('new_column', lit(None).cast(StringType())) 

Un esempio completo:

df = sc.parallelize([row(1, "2"), row(2, "3")]).toDF() 
df.printSchema() 

## root 
## |-- foo: long (nullable = true) 
## |-- bar: string (nullable = true) 

new_df = df.withColumn('new_column', lit(None).cast(StringType())) 
new_df.printSchema() 

## root 
## |-- foo: long (nullable = true) 
## |-- bar: string (nullable = true) 
## |-- new_column: string (nullable = true) 

new_df.show() 

## +---+---+----------+ 
## |foo|bar|new_column| 
## +---+---+----------+ 
## | 1| 2|  null| 
## | 2| 3|  null| 
## +---+---+----------+ 

A Scala equivalente può essere trovato qui: Create new Dataframe with empty/null field values

+0

Come fare questo condizionalmente, se la colonna non esiste in primo luogo? Sto cercando di usare UDF e passare il DF a questo e poi facendo 'new_column non nel controllo df.columns', ma non riesco a farlo funzionare. – Gopala

+0

@Gopala Questo aiuto: http://stackoverflow.com/q/35904136/1560062? – zero323

+0

Anch'io l'ho guardato, ma non ero ancora in grado di incorporarlo condizionatamente in un 'withColumn ('blah', dove (has_column (df ['blah']) == False) ....' tipo di costrutto. Deve mancare qualche costrutto sintattico.Voglio aggiungere una colonna con Nulls, se non esiste.Questa risposta fa la prima, l'altra controlla quest'ultima. – Gopala

-2

I cast verrebbe attivato (Nessuno) in NullType anziché in StringType. In modo che se abbiamo mai per filtrare le righe non nulle su quella colonna ... può essere facilmente fatto come segue

df = sc.parallelize([Row(1, "2"), Row(2, "3")]).toDF() 

new_df = df.withColumn('new_column', lit(None).cast(NullType())) 

new_df.printSchema() 

df_null = new_df.filter(col("new_column").isNull()).show() 
df_non_null = new_df.filter(col("new_column").isNotNull()).show() 

anche essere attenti a non usare acceso ("Nessuno") (con le virgolette) se si stanno trasmettendo a StringType poiché non riuscirebbe a cercare i record con condizione di filtro .isNull() su col ("new_column").