Python Spark DataFrame嵌套列查询及报错解决
解决Spark DataFrame嵌套数组字段访问的错误
错误原因分析
你遇到的cannot resolve 'result.resuLt['dstopsize']'错误,核心原因有两个:
- 数组类型不能直接用字段名访问:
result是array<struct>类型,里面的resuLt也是array<struct>——Spark对数组的访问需要整数索引(比如result[0]取第一个元素),而你传入了字符串dstopsize,导致类型不匹配。 - 字段路径可能有误:从你的Schema来看,
dstopsize字段实际在result.result(内层小写的result数组)的结构体元素中,而不是resuLt(大写L)数组里,可能是你拼写时混淆了大小写。
解决方案
根据你的需求(既要访问嵌套字段,又要保留原数组内容),分两种场景给出代码:
场景1:展开数组,查看每个元素的dstopsize
如果想把嵌套数组展开成扁平的行,方便查看每个dstopsize的具体值,可以用explode函数逐层展开数组:
// Scala示例 import org.apache.spark.sql.functions.explode // 先展开外层result数组,得到每个hop的结构体 val explodedResult = file_df.select(explode($"result").alias("result_element")) // 再展开内层的result数组,得到包含dstopsize的结构体,同时保留原数组内容 explodedResult.select( $"result_element", // 保留原result元素的全部内容 explode($"result_element.result").alias("inner_result_element") ).select( $"result_element", $"inner_result_element.dstoptsize".alias("dstopsize") ).show(10)
# PySpark示例 from pyspark.sql.functions import explode exploded_result = file_df.select(explode("result").alias("result_element")) exploded_result.select( "result_element", explode("result_element.result").alias("inner_result_element") ).select( "result_element", "inner_result_element.dstoptsize" ).show(10)
场景2:保留数组结构,提取所有dstopsize到数组中
如果不想展开数组,而是要把每个result元素下的所有dstopsize收集成一个数组,可以用transform函数嵌套处理:
// Scala示例 import org.apache.spark.sql.functions.transform file_df.select( $"result", // 保留原result数组全部内容 transform( $"result", elem => transform(elem.result, innerElem => innerElem.dstoptsize) ).alias("all_dstopsize") ).show(10, truncate = false)
# PySpark示例 from pyspark.sql.functions import expr file_df.select( "result", expr("transform(result, elem -> transform(elem.result, innerElem -> innerElem.dstoptsize))").alias("all_dstopsize") ).show(10, truncate=False)
补充:访问resuLt数组的字段
如果你确实需要访问resuLt(大写L)数组里的字段(比如from、rtt),同样的逻辑:要么用explode展开,要么用transform提取。例如提取resuLt里的rtt:
# PySpark示例,提取resuLt中的rtt数组 file_df.select( "result", expr("transform(result, elem -> transform(elem.resuLt, innerElem -> innerElem.rtt))").alias("all_resuLt_rtt") ).show(10)
注意事项
因为你的Spark开启了大小写敏感,所以必须严格匹配字段名的大小写:
- 外层数组:
result(全小写) - 内层数组1:
resuLt(大写L) - 内层数组2:
result(全小写) - 目标字段:
dstoptsize(全小写)
内容的提问来源于stack exchange,提问作者crystyxn
相关产品推荐
相关产品推荐

