Spark DataFrame聚合后别名未生效问题及修改方案咨询
问题分析与解决方案
嗨,我明白你遇到的问题了——你设置的别名没生效,是因为你把alias()用错地方啦!
为什么别名不生效?
你现在的写法是把.alias()放在了聚合函数的内部参数里,比如:
count(lit(1).alias("OVERALL_COUNT"))
但Spark的聚合函数(比如count、sum)会把整个传入的表达式直接作为生成列的名称,不会解析你在参数里设置的别名。所以最终列名变成了count(1 AS OVERALL_COUNT)这种完整表达式,而不是你想要的OVERALL_COUNT。
如何修改代码?
你需要把别名应用在整个聚合函数的结果上,有两种常用的写法:
写法1:在聚合函数后添加.alias()
把alias()移到聚合函数外面,包裹整个聚合表达式:
val maleFemaleDistribution = initDF .select("DISTRICT","GENDER","ENROLMENT_ACCEPTED","ENROLMENT_REJECTED") .groupBy("DISTRICT") .agg( count(lit(1)).alias("OVERALL_COUNT"), // 别名放在聚合函数后 sum(when(col("GENDER") === "M", 1).otherwise(0)).alias("MALE_COUNT"), sum(when(col("GENDER") === "F", 1).otherwise(0)).alias("FEMALE_COUNT") ) .orderBy("DISTRICT")
写法2:在agg中使用键值对(列名 -> 聚合表达式)
Spark的agg方法支持传入Map形式的参数,直接指定列名和对应的聚合逻辑,这种写法更清晰:
val maleFemaleDistribution = initDF .select("DISTRICT","GENDER","ENROLMENT_ACCEPTED","ENROLMENT_REJECTED") .groupBy("DISTRICT") .agg( "OVERALL_COUNT" -> count(lit(1)), "MALE_COUNT" -> sum(when(col("GENDER") === "M", 1).otherwise(0)), "FEMALE_COUNT" -> sum(when(col("GENDER") === "F", 1).otherwise(0)) ) .orderBy("DISTRICT")
修改后的效果
现在执行maleFemaleDistribution.printSchema(),就能得到你期望的输出:
root |-- DISTRICT: string (nullable = true) |-- OVERALL_COUNT: long (nullable = false) |-- MALE_COUNT: long (nullable = true) |-- FEMALE_COUNT: long (nullable = true)
内容的提问来源于stack exchange,提问作者Rajesh Ravindran
相关产品推荐
相关产品推荐

