PySpark实现单行多列转多行:动态生成列名值组合行
解决PySpark DataFrame列名与值动态转换为行的问题
实现思路
将每一行的所有列名与对应值打包成结构体数组,通过explode把数组拆分为单独行,再动态生成需要的组合字符串列,完全适配动态列数和多行场景。
完整代码实现
from pyspark.sql import SparkSession from pyspark.sql.functions import col, explode, array, struct, concat_ws, when, lit # 初始化SparkSession spark = SparkSession.builder.appName("DynamicColToRow").getOrCreate() # 示例输入DataFrame(支持多行、动态列数) data = [("baz", "bim"), ("qux", None)] df = spark.createDataFrame(data, ["foo", "bar"]) print("原始DataFrame:") df.show() # 获取所有列名,动态构造结构体数组 columns = df.columns col_structs = array(*[struct(lit(c).alias("col_name"), col(c).alias("value")) for c in columns]) # 添加数组列并拆分 df_with_struct = df.withColumn("col_pairs", col_structs) df_exploded = df_with_struct.select(explode("col_pairs").alias("pair")) # 生成目标列 result_df = df_exploded.select( # new_column1:列名与值用指定符号拼接 concat_ws(" = ", col("pair.col_name"), col("pair.value")).alias("new_column1"), # new_column2:根据值是否为空拼接不同内容 when(col("pair.value").isNull(), concat_ws(" is ", col("pair.col_name"), lit("null"))) .otherwise(concat_ws(" is ", col("pair.col_name"), col("pair.value"))).alias("new_column2") ) print("\n转换后DataFrame:") result_df.show(truncate=False)
关键说明
- 动态列处理:通过
df.columns自动获取所有列名,循环生成结构体,无需硬编码列名,适配任意列数的DataFrame - 多行支持:
explode操作会针对原DataFrame的每一行,将其所有列转换为对应行数,自然支持多行输入 - 空值适配:使用
when函数判断值是否为null,生成符合需求的字符串格式 - 纯PySpark实现:全程使用PySpark原生API,无需依赖pandas
内容的提问来源于stack exchange,提问作者ndycuong
相关产品推荐
相关产品推荐

