求助:如何实现Spark DataFrame列值转列名(长表转宽表)
解决方案
这是Spark中典型的**透视(Pivot)**场景,通过分组+透视操作即可实现需求,以下是Python和Scala两种常用语言的实现代码:
Python 实现
from pyspark.sql import SparkSession from pyspark.sql.functions import first # 初始化SparkSession spark = SparkSession.builder.appName("pivot_example").getOrCreate() # 模拟现有DataFrame data = [ ("starttime", "2022-08-04 10:00:00", "abc"), ("endtime", "2022-08-04 10:20:00", "abc"), ("starttime", "2022-08-04 10:10:00", "xyz"), ("endtime", "2022-08-04 10:50:00", "xyz") ] df = spark.createDataFrame(data, ["tagname", "tagvalue", "filename"]) # 执行分组透视操作 result_df = df.groupBy("filename") \ .pivot("tagname") \ .agg(first("tagvalue")) \ .select("filename", "starttime", "endtime") # 调整列顺序 # 查看结果 result_df.show(truncate=False)
Scala 实现
import org.apache.spark.sql.SparkSession import org.apache.spark.sql.functions.first // 初始化SparkSession val spark = SparkSession.builder.appName("pivot_example").getOrCreate() // 模拟现有DataFrame val data = Seq( ("starttime", "2022-08-04 10:00:00", "abc"), ("endtime", "2022-08-04 10:20:00", "abc"), ("starttime", "2022-08-04 10:10:00", "xyz"), ("endtime", "2022-08-04 10:50:00", "xyz") ) val df = spark.createDataFrame(data).toDF("tagname", "tagvalue", "filename") // 执行分组透视操作 val resultDf = df.groupBy("filename") .pivot("tagname") .agg(first("tagvalue")) .select("filename", "starttime", "endtime") // 调整列顺序 // 查看结果 resultDf.show(false)
关键说明
groupBy("filename"):按filename分组,确保每个文件的记录聚合到一行pivot("tagname"):将tagname列的不同值转换为新的列名agg(first("tagvalue")):因为每个分组下的每个tagname对应唯一的tagvalue,所以用first(或max/min)提取对应值select步骤用于调整列的显示顺序,让filename排在最前面
内容的提问来源于stack exchange,提问作者Anand Kulkarni
相关产品推荐
相关产品推荐

