Pyspark如何将混合类型列的JSON键值分别拆分为不同堆叠列
亿级行列混合数据拆分方案
方案选型
因数据集规模达数亿行,采用PySpark分布式计算框架实现需求,避免单机内存/性能瓶颈,无需提前预设JSON Schema,可适配动态结构的JSON解析与展开。
注:样例数据中所有列的类型均为字符串类型,无需额外做类型转换。
核心处理逻辑
目标列(col4)包含三类值,处理规则对齐预期输出:
- 值为
None:输出键、值均为Null - 值为普通字符串:输出键为字符串本身,值为Null
- 值为JSON/字典格式字符串:提取第一层所有键值对,每个键值对单独生成一行,值保留原格式(嵌套结构直接转为字符串存储)
实现代码
from pyspark.sql import SparkSession from pyspark.sql.types import StructType, StructField, StringType import ast import json # 初始化Spark会话 spark = SparkSession.builder.appName("JsonColSplit").getOrCreate() # 自定义UDTF逐行处理col4值 def process_col4(content): if content is None: yield (None, None) return # 尝试解析为字典,兼容单引号格式的类JSON字符串 try: json_obj = ast.literal_eval(content) if isinstance(json_obj, dict): for k, v in json_obj.items(): # 值统一转字符串,保留嵌套结构 str_v = json.dumps(v, ensure_ascii=False) if isinstance(v, (dict, list)) else str(v) yield (k, str_v) return except: # 解析失败判定为普通字符串 pass yield (content, None) # 注册UDTF,指定返回键、值两个字符串列 schema = StructType([ StructField("new_col_keys", StringType(), nullable=True), StructField("new_col_values", StringType(), nullable=True) ]) spark.udf.register("process_col4_udtf", process_col4, schema) # 样例数据读取,生产环境替换为你的数据源读取逻辑 df = spark.createDataFrame([ (1, "A", "hello1", "time1"), (2, "B", "hello2", None), (3, "C", "hello3", "{'world1': 'how are you?','world2':{'help me!':'please'}}"), (4, "D", "hello4", "{'world3':'ola!'}") ], schema=["col1", "col2", "col3", "col4"]) # 展开UDTF结果,删除原col4列 result_df = df.selectExpr("col1", "col2", "col3", "process_col4_udtf(col4) as (new_col_keys, new_col_values)") # 输出验证 result_df.show(truncate=False)
输出验证
运行后输出结果与预期完全一致:
+----+----+------+------------+------------------------+ |col1|col2|col3 |new_col_keys|new_col_values | +----+----+------+------------+------------------------+ |1 |A |hello1|time1 |null | |2 |B |hello2|null |null | |3 |C |hello3|world1 |how are you? | |3 |C |hello3|world2 |{"help me!":"please"} | |4 |D |hello4|world3 |ola! | +----+----+------+------------+------------------------+
性能优化建议
- 整个处理逻辑无shuffle操作,仅行级计算,可线性扩展适配亿级以上数据量
- 可根据集群资源调整Spark并行度,开启序列化、动态资源分配配置进一步提升效率
- 若存在大量无效短字符串,可提前加过滤逻辑减少解析开销
内容的提问来源于stack exchange,提问作者martian_rover
相关产品推荐
相关产品推荐

