tutorial started spark software getting scala apache-spark apache-spark-sql

scala - started - spark python



¿Es posible alias columnas programáticamente en spark sql? (4)

Resulta def toDF(colNames: String*): DataFrame hace exactamente eso. Pegado de la documentación 2.11.7:

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"

En spark SQL (quizás solo HiveQL) uno puede hacer:

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

lo que daría como resultado un DataFrame con columnas llamadas "sex" y "avg_age" .

¿Cómo se puede alias a avg(age) a "avg_age" sin usar SQL textual?

Editar: Después de la respuesta de zero323, necesito agregar la restricción que:

El nombre de la columna a ser renombrada puede no ser conocido / garantizado o incluso direccionable . En SQL textual, el uso de "seleccionar EXPR como NAME" elimina el requisito de tener un nombre intermedio para EXPR. Este también es el caso en el ejemplo anterior, donde "avg (edad)" podría obtener una variedad de nombres generados automáticamente (que también varían entre lanzamientos de chispa y backends de contexto SQL).


Las columnas anónimas, como la que generaría avg(age) sin AS avg_age , recibirán automáticamente nombres asignados. Como usted señala en su pregunta, los nombres son específicos de la implementación, generados por una estrategia de nombres. Si es necesario, puede escribir un código que olfatea el entorno y crea una estrategia apropiada de descubrimiento y cambio de nombre basada en la estrategia de nomenclatura específica. No hay muchos de ellos.

En Spark 1.4.1 con HiveContext , el formato es "_c N " donde N es la posición de la columna anónima en la tabla. En tu caso, el nombre sería _c1 .


Si prefiere cambiar el nombre de una sola columna, puede usar el método withColumnRenamed :

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

Alternativamente, puede usar el método de alias :

import org.apache.spark.sql.functions.avg df.select(avg($"age").alias("average_age"))

Puedes llevarlo más lejos con un pequeño ayudante:

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


Supongamos que human_df es el DataFrame para humanos. Desde Spark 1.3:

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