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

PySpark DataFrame数值列拆分为多行的实现方法咨询

PySpark宽表转长表实现方案

你需要实现的是典型的宽表转长表(Unpivot)操作,有以下两种可行实现思路:

方案1:使用stack函数实现Unpivot(性能最优,推荐)

直接使用PySpark内置的逆透视函数完成列转行,仅需扫描一次原表,性能远高于多次扫描的方案,示例代码如下:

from pyspark.sql import functions as F

# 1. 先处理百分比列,添加%后缀
df_processed = df.withColumn("values_in_percent", F.concat(F.col("values_in_percent"), F.lit("%")))

# 2. 使用stack函数完成列转行,拆分出key_1和临时值列
df_unpivot = df_processed.select(
    "Region", "Location", "Month", "Services", "Type",
    F.expr("stack(2, 'values_in_millions', values_in_millions, 'values_in_percent', values_in_percent) as (key_1, temp_value)")
)

# 3. 拆分出values_1和values_2列
df_result = df_unpivot.withColumn(
    "values_1", F.when(F.col("key_1") == "values_in_millions", F.col("temp_value")).otherwise(None)
).withColumn(
    "values_2", F.when(F.col("key_1") == "values_in_percent", F.col("temp_value")).otherwise(None)
).drop("temp_value")

方案2:使用unionAll拼接实现(逻辑直观,适合新手)

把两个值列分别处理成对应的子数据集,再合并为最终结果,逻辑简单易懂:

from pyspark.sql import functions as F

# 处理values_in_millions对应的子数据集
df_million = df.select(
    "Region", "Location", "Month", "Services", "Type",
    F.lit("values_in_millions").alias("key_1"),
    F.col("values_in_millions").alias("values_1"),
    F.lit(None).alias("values_2")
)

# 处理values_in_percent对应的子数据集
df_percent = df.select(
    "Region", "Location", "Month", "Services", "Type",
    F.lit("values_in_percent").alias("key_1"),
    F.lit(None).alias("values_1"),
    F.concat(F.col("values_in_percent"), F.lit("%")).alias("values_2")
)

# 合并两个子数据集得到最终结果
df_result = df_million.unionAll(df_percent)

注意事项

  • 如果你不需要把百分比存为带%的字符串,仅需保留数值类型,去掉F.concat(F.col("values_in_percent"), F.lit("%"))这部分逻辑即可。
  • 如果你后续需要扩展更多值列,优先选择stack方案,可避免重复扫描原表带来的性能损耗。

内容的提问来源于stack exchange,提问作者user175025

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:15:11