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

Spark:将单分隔符分隔字符串转为键值对DataFrame列

解决方案

一、基于固定键列表的实现

如果已知所有可能的键名,这个方案直接高效:

  1. 先将字符串按空格拆分为数组:
import org.apache.spark.sql.functions._

// 示例数据
val df = spark.createDataFrame(Seq(
  ("key1 val1 key2 val2 key3 val3"),
  ("key1 val4 key2 val5 key3 val6")
)).toDF("raw_str")

val split_df = df.withColumn("split_arr", split(col("raw_str"), "\\s+"))
  1. 针对每个固定键提取对应值:
    假设固定键列表为["key1", "key2", "key3"],通过定位键在数组中的索引,取其下一个元素作为对应值:
val key_list = List("key1", "key2", "key3")

val result_df = key_list.foldLeft(split_df) { (temp_df, key) =>
  temp_df.withColumn(key, element_at(col("split_arr"), array_position(col("split_arr"), key) + 1))
}.drop("raw_str", "split_arr")

result_df.show()

输出结果:

+----+----+----+
|key1|key2|key3|
+----+----+----+
|val1|val2|val3|
|val4|val5|val6|
+----+----+----+

二、动态处理未知键名和数量

如果键的名称、数量不确定,需先收集所有唯一键,再动态生成列:

  1. 拆分字符串为数组,生成键值对结构:
    利用zip_with将数组中偶数索引(键)和奇数索引(值)配对(Spark数组为0-based):
val split_df = df.withColumn("split_arr", split(col("raw_str"), "\\s+"))

// 生成键值对数组:取偶数索引元素为key,奇数索引元素为value
val kv_df = split_df.withColumn(
  "kv_pairs",
  zip_with(
    slice(col("split_arr"), 1, size(col("split_arr")), 2), // 提取所有键(对应0-based的0、2、4...位)
    slice(col("split_arr"), 2, size(col("split_arr")), 2), // 提取所有值(对应0-based的1、3、5...位)
    (k, v) => struct(k.as("key"), v.as("value"))
  )
)
  1. 展开键值对并通过pivot生成列:
// 若原数据有唯一行标识(如id列),需替换groupBy的参数为该列,避免行数据聚合
val exploded_df = kv_df.select(explode(col("kv_pairs")).as("kv"))
val final_df = exploded_df.groupBy()
  .pivot(col("kv.key"))
  .agg(first(col("kv.value")))

final_df.show()

注意事项

  • 若行内存在重复键,可将first替换为collect_list保留所有值,或根据业务需求选择聚合函数
  • 拆分时用\\s+而非 ,避免连续空格产生空元素

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:35:25