2015-07-21 13 views
14

In SQL scintilla (forse solo HiveQL) si può fare:E 'possibile programmare le colonne alias in spark sql?

select sex, avg(age) as avg_age 
from humans 
group by sex 

che si tradurrebbe in un DataFrame con colonne denominate "sex" e "avg_age".

Come può avg(age) essere coniato a "avg_age" senza l'utilizzo di SQL testuale?

Edit: Dopo la risposta s' zero323, ho bisogno di aggiungere il vincolo che:

del nome della colonna-to-be-rinominato non può essere conosciuto/garantito o anche indirizzabile. In SQL testuale, l'utilizzo di "seleziona ESPR come NOME" rimuove il requisito di avere un nome intermedio per EXPR. Questo è anche il caso dell'esempio sopra, in cui "avg (age)" potrebbe ottenere una varietà di nomi generati automaticamente (che variano anche tra versioni spark e backl contest SQL).

+0

è possibile aggiungere un alias per il proprio df. –

risposta

24

Supponiamo che human_df sia il DataFrame per l'uomo. Dal momento che Spark 1.3:

human_df.groupBy("sex").agg(avg("age").alias("avg_age")) 
+1

È questo Scala? Sembra Python. – summerbulb

7

Si scopre che def toDF(colNames: String*): DataFrame fa esattamente questo. Incollare da 2.11.7 documentazione:

def toDF(colNames: String*): DataFrame 

Returns a new DataFrame with columns renamed. This can be quite 
convenient in conversion from a RDD of tuples into a DataFrame 
with meaningful names. For example: 

    val rdd: RDD[(Int, String)] = ... 
    rdd.toDF() // this implicit conversion creates a DataFrame 
       // with column name _1 and _2 
    rdd.toDF("id", "name") // this creates a DataFrame with 
          // column name "id" and "name" 
11

Se si preferisce rinominare una singola colonna, è possibile utilizzare il metodo withColumnRenamed:

case class Person(name: String, age: Int) 

val df = sqlContext.createDataFrame(
    Person("Alice", 2) :: Person("Bob", 5) :: Nil) 
df.withColumnRenamed("name", "first_name") 

In alternativa è possibile utilizzare il metodo alias:

import org.apache.spark.sql.functions.avg 

df.select(avg($"age").alias("average_age")) 

Puoi continuare con il piccolo aiuto:

import org.apache.spark.sql.Column 

def normalizeName(c: Column) = { 
    val pattern = "\\W+".r 
    c.alias(pattern.replaceAllIn(c.toString, "_")) 
} 

df.select(normalizeName(avg($"age"))) 
1

Colonne anonime, come quella che verrebbe generata da avg(age) senza AS avg_age, ricevono automaticamente i nomi assegnati. Come fai notare nella tua domanda, i nomi sono specifici dell'implementazione, generati da una strategia di denominazione. Se necessario, è possibile scrivere codice che annusa l'ambiente e crea un'appropriata scoperta della strategia di ridenominazione & in base alla strategia di denominazione specifica. Non ce ne sono molti.

In Spark 1.4.1 con HiveContext, il formato è "_c N" dove N è la posizione della colonna anonima nella tabella. Nel tuo caso, il nome sarebbe _c1.

Problemi correlati