在spark SQL(可能只有HiveQL)中,可以做到:
select sex, avg(age) as avg_age
from humans
group by sex
这会产生DataFrame
,其中包含名为"sex"
和"avg_age"
的列。
如果avg(age)
不使用文本SQL,"avg_age"
如何别名?
修改 在零323的回答之后,我需要添加以下约束:
要重命名的列名称可能未知/保证甚至无法寻址。在文本SQL中,使用"选择EXPR作为NAME"删除了具有EXPR中间名称的要求。在上面的例子中也是这种情况,其中" avg(年龄)"可以获得各种自动生成的名称(在spark发布和sql-context后端之间也有所不同)。
答案 0 :(得分:32)
我们假设human_df
是人类的DataFrame。自Spark 1.3开始:
human_df.groupBy("sex").agg(avg("age").alias("avg_age"))
答案 1 :(得分:17)
如果您希望重命名单个列,则可以使用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")))
答案 2 :(得分:9)
原来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"
答案 3 :(得分:1)
匿名列,例如由avg(age)
生成而没有AS avg_age
的列,会自动分配名称。正如您在问题中指出的那样,名称是特定于实现的,由命名策略生成。如果需要,您可以编写能够嗅探环境并实例化适当发现的代码。根据特定的命名策略重命名策略。它们并不多。
在带有HiveContext
的Spark 1.4.1中,格式为" _c N "其中 N 是表中匿名列的位置。在您的情况下,名称将为_c1
。