如何在Scala中复制Spark DataFrame单行元素生成数组?
解决方案:将单行字段转换为重复指定次数的数组
嘿,这个需求很清晰,我给你两种实用的Spark实现方案,适配不同版本的Spark:
方法一:使用array_repeat(Spark 2.4+ 推荐)
Spark 2.4及以上版本提供了array_repeat函数,可以直接将单个值重复指定次数生成数组,搭配size函数获取原数组的长度作为重复次数,完美匹配需求。
步骤代码:
// 导入所需函数 import org.apache.spark.sql.functions.{array_repeat, size} // 处理DataFrame val resultDf = testDf.select( array_repeat($"one", size($"Array")).alias("one"), array_repeat($"two", size($"Array")).alias("two"), array_repeat($"X", size($"Array")).alias("X"), $"Array" // 保留原数组字段 ) // 查看结果 resultDf.show(false)
输出结果:
+------------+------------+------------+------------+ |one |two |X |Array | +------------+------------+------------+------------+ |[1, 1, 1, 1]|[2, 2, 2, 2]|[x, x, x, x]|[1, 2, 3, 4]| +------------+------------+------------+------------+
方法二:兼容低版本Spark(Spark < 2.4)
如果你的Spark版本低于2.4,没有array_repeat函数,可以通过explode拆分原数组,再分组聚合的方式实现:
步骤代码:
// 导入所需函数 import org.apache.spark.sql.functions.{explode, collect_list} // 处理DataFrame val resultDf = testDf .withColumn("dummy", explode($"Array")) // 将原数组拆分为多行,每行对应一个元素 .groupBy($"Array") // 以原数组为分组键 .agg( collect_list($"one").alias("one"), collect_list($"two").alias("two"), collect_list($"X").alias("X") ) .select("one", "two", "X", "Array") // 调整列顺序与原DataFrame一致 // 查看结果 resultDf.show(false)
原理说明:
通过explode将原数组的每个元素拆成一行,这样每行对应原数组的一个位置;再通过groupBy和collect_list将每个字段的单个值收集成数组,因为原字段值在每行都是相同的,最终收集的数组就是重复对应次数的结果。
内容的提问来源于stack exchange,提问作者sanyi14ka
相关产品推荐
相关产品推荐

