You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark SQL中如何将多列拆分为多行并保留列名信息

嗨,我来帮你搞定这个需求!你需要把col3、col4、col5这几列拆成单行,同时保留对应的列名作为col_num,Spark 2.2.0有两种很实用的方法可以实现:

方法1:用struct+array+explode组合

这个方法先把每个目标列的列名和对应值打包成结构体,再放到数组里,最后展开数组提取字段:

import org.apache.spark.sql.functions.{array, col, explode, lit, struct}

// 假设你的原始DataFrame名为df
val transformedDF = df.select(
  col("col1"),
  col("col2"),
  array(
    struct(lit("col3").as("col_num"), col("col3").as("col_new")),
    struct(lit("col4").as("col_num"), col("col4").as("col_new")),
    struct(lit("col5").as("col_num"), col("col5").as("col_new"))
  ).as("cols_array")
)

val resultDF = transformedDF
  .withColumn("cols", explode(col("cols_array")))
  .select(
    col("col1"),
    col("col2"),
    col("cols.col_num"),
    col("cols.col_new")
  )

resultDF.show()

方法2:用stack函数(更简洁)

Spark 2.2.0支持stack函数,它可以直接把多列转成键值对形式,一步到位:

import org.apache.spark.sql.functions.stack

val resultDF = df.select(
  col("col1"),
  col("col2"),
  stack(3,  // 要转换的列的数量
    "col3", col("col3"),
    "col4", col("col4"),
    "col5", col("col5")
  ).as(Seq("col_num", "col_new"))  // 给转换后的两列命名
)

resultDF.show()

为什么你的之前尝试没得到col_num?

你之前用array+explode只把列的值放进了数组,没有把列名和值绑定在一起,所以展开后丢失了列名信息。上面两种方法都把列名(用lit生成固定字符串或者直接在stack里传入)和对应值关联起来,这样就能同时保留你需要的col_num和col_new了。

内容的提问来源于stack exchange,提问作者alex-arkhipov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:25:27