Spark转置并展开嵌套数组列时多列处理返回空DataFrame问题
问题根因
你的代码返回空结果核心原因是:当某行的待转换列值为null时,TRANSFORM作用在null数组上返回结果也是null,f.array()拼接多个表达式结果时如果包含null元素,后续flatten操作会直接返回null,最终inline处理null就不会输出任何行。
比如id=1的行,b列为null,对应的TRANSFORM表达式返回null,拼接后的array为[<a列转换后的数组>, null],flatten后整体为null,没有可展开的内容。
同时你提供的测试代码中JSON字符串多了冗余的右括号,也会导致测试数据构造异常,修正方案中同步做了调整。
修正方案
只需要在转换每列的时候,用coalesce把null数组替换为空数组即可,修正后的代码如下:
import pyspark.sql.functions as f # 构造测试数据 df = spark.read.json(sc.parallelize([ """{"id":1,"a":[{"date":1,"val":1},{"date":11,"val":11}]}""", """{"id":2,"b":[{"date":2,"val":2}]}"""])) cols = ['a', 'b'] # 对每列转换时添加coalesce处理null,替换为空数组 expressions = [ f.expr(f'coalesce(TRANSFORM({col}, el -> STRUCT("{col}" AS cols, el.date, el.val)), array())') for col in cols ] transpose_df = df.withColumn('arrays', f.flatten(f.array(*expressions))) # 若需要输出要求1的transpose_df,打开下面一行注释即可 # transpose_df = transpose_df.select('id', f.explode('arrays').alias('arr_struct')).select('id', f.col('arr_struct.cols').alias('cols'), f.col('arr_struct').alias('arrays')) explode_df = transpose_df.selectExpr('id', 'inline(arrays)') explode_df.show()
运行结果
运行修正后的代码即可得到要求输出2的结果:
+---+----+----+---+ | id|cols|date|val| +---+----+----+---+ | 1| a| 1| 1| | 1| a| 11| 11| | 2| b| 2| 2| +---+----+----+---+
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

