2015-07-21 20 views
14

In Funken SQL (vielleicht nur HiveQL) kann man tun:Ist es möglich, Spalten Spalten in Spark Sql programmgesteuert?

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

, die in einem DataFrame mit Spalten namens "sex" und "avg_age" führen würde.

Wie kann avg(age) zu "avg_age" Aliasing ohne Verwendung von Text SQL?

Edit: Nach zero323 ‚s Antwort, ich brauche die Einschränkung hinzufügen, dass:

Die Säule-zu-sein-umbenannt Name/nicht bekannt garantiert werden kann oder sogar adressierbaren. In textuellem SQL entfernt die Verwendung von "EXPR als NAME auswählen" die Anforderung, einen Zwischennamen für EXPR zu haben. Dies ist auch in dem obigen Beispiel der Fall, wo "avg (age)" eine Vielzahl von automatisch generierten Namen erhalten könnte (die auch zwischen Spark-Releases und sql-Kontext-Backends variieren).

+0

können Sie einen Alias ​​für Ihre df hinzufügen. –

Antwort

24

Nehmen wir an human_df ist der DataFrame für Menschen. Seit Spark 1.3:

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

Ist das Scala? Es sieht wie Python aus. – summerbulb

7

Stellt sich heraus def toDF(colNames: String*): DataFrame tut genau das. Einfügen von 2.11.7 Dokumentation:

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

Wenn Sie es vorziehen, eine einzelne Spalte umbenennen es möglich ist, withColumnRenamed Methode zu verwenden:

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

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

Alternativ können Sie alias Methode verwenden:

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

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

Sie können es weiter mit kleinen Helfer:

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

Anonyme Spalten, wie die, die von avg(age) ohne AS avg_age generiert werden, erhalten automatisch zugewiesene Namen. Wie Sie in Ihrer Frage angeben, sind die Namen implementierungsspezifisch und werden durch eine Benennungsstrategie generiert. Bei Bedarf könnten Sie Code schreiben, der die Umgebung aufschnüffelt und eine entsprechende Erkennungsstrategie basierend auf der spezifischen Benennungsstrategie instanziiert &. Es gibt nicht viele von ihnen.

in funken 1.4.1 mit HiveContext, ist das Format "_C N", wobei N ist die Position der anonymen Spalte in der Tabelle. In Ihrem Fall wäre der Name _c1.

Verwandte Themen