Возможно ли псевдоним столбцов программно в спарк SQL?

scala apache-spark apache-spark-sql

54249 просмотра

4 ответа

1586 Репутация автора

В Spark SQL (возможно, только HiveQL) можно сделать:

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

что приведет к DataFrameстолбцам с именами "sex"и "avg_age".

Как можно avg(age)использовать псевдонимы "avg_age"без использования текстового SQL?

Изменить: После ответа ноль 323 мне нужно добавить ограничение, которое:

Имя столбца, подлежащего переименованию, может быть неизвестным / не гарантированным или даже не адресуемым . В текстовом SQL использование «выбрать EXPR в качестве ИМЯ» устраняет необходимость иметь промежуточное имя для EXPR. Это также имеет место в приведенном выше примере, где «avg (age)» может получить множество автоматически сгенерированных имен (которые также различаются в разных версиях spark и в бэкэндах sql-context).

Автор: Prikso NAI Источник Размещён: 21.07.2015 12:07

Ответы (4)


10 плюса

1586 Репутация автора

Решение

Оказывается, def toDF(colNames: String*): DataFrameделает именно это. Склеивание от 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"
Автор: Prikso NAI Размещён: 21.07.2015 12:34

17 плюса

193195 Репутация автора

Если вы предпочитаете переименовать один столбец, можно использовать withColumnRenamedметод:

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

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

В качестве альтернативы вы можете использовать aliasметод:

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

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

Вы можете пойти дальше с помощью небольшого помощника:

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")))
Автор: zero323 Размещён: 21.07.2015 12:53

1 плюс

7811 Репутация автора

Анонимные столбцы, такие как тот, который будет создан avg(age)без AS avg_age, получают автоматически назначенные имена. Как вы указали в своем вопросе, имена зависят от реализации и генерируются стратегией именования. При необходимости вы можете написать код, который анализирует среду и создает соответствующую стратегию обнаружения и переименования, основанную на конкретной стратегии именования. Их не так много.

В Spark 1.4.1 с HiveContextформатом является «_c N », где N - позиция анонимного столбца в таблице. В вашем случае имя будет _c1.

Автор: Sim Размещён: 25.07.2015 05:47

32 плюса

536 Репутация автора

Предположим, human_dfэто DataFrame для людей. Начиная с Spark 1.3:

human_df.groupBy("sex").agg(avg("age").alias("avg_age"))
Автор: Robert Chevallier Размещён: 29.11.2015 05:52
Вопросы из категории :
32x32