Spark Scala:如何按输入序列复制DataFrame每行数据?
实现方案
你可以通过交叉连接或数组展开的方式,快速生成目标货币对应的行并与原数据合并,以下是具体实现:
方法一:使用交叉连接(Cross Join)
import org.apache.spark.sql.SparkSession import org.apache.spark.sql.functions._ object DuplicateRowsDemo { def main(args: Array[String]): Unit = { val spark = SparkSession.builder() .appName("DuplicateRowsByCurrency") .master("local[*]") .getOrCreate() import spark.implicits._ // 模拟输入数据集 val originalDF = Seq( (1, "USD", 10), (1, "EUR", 20), (2, "USD", 30), (2, "EUR", 40) ).toDF("id", "currency", "value") // 输入目标货币序列 val targetCurrencies = Seq("JPY") // 转换为临时DataFrame用于交叉连接 val currencyDF = targetCurrencies.toDF("new_currency") // 生成新行:交叉连接后替换currency字段 val newRowsDF = originalDF .crossJoin(currencyDF) .withColumn("currency", col("new_currency")) .drop("new_currency") // 合并原数据与新生成数据 val finalDF = originalDF.union(newRowsDF) // 输出结果 finalDF.show() } }
方法二:使用数组展开(Explode)
如果目标货币序列较长,这种方式更简洁高效:
import org.apache.spark.sql.SparkSession import org.apache.spark.sql.functions._ object DuplicateRowsDemo { def main(args: Array[String]): Unit = { val spark = SparkSession.builder() .appName("DuplicateRowsByCurrency") .master("local[*]") .getOrCreate() import spark.implicits._ val originalDF = Seq( (1, "USD", 10), (1, "EUR", 20), (2, "USD", 30), (2, "EUR", 40) ).toDF("id", "currency", "value") val targetCurrencies = Seq("JPY") // 直接将序列转为数组,通过explode生成多行 val newRowsDF = originalDF .withColumn("new_currency", explode(lit(targetCurrencies))) .withColumn("currency", col("new_currency")) .drop("new_currency") val finalDF = originalDF.union(newRowsDF) finalDF.show() } }
代码说明
- 原数据构造:用
Seq模拟你的输入数据集,转换为指定列名的DataFrame。 - 生成新行:两种方法本质都是让原数据的每一行与目标货币逐一配对,替换
currency字段为目标货币。 - 合并数据:通过
union将原数据和新生成的行合并,得到最终结果。
如果输入序列包含多个货币(比如Seq("JPY", "GBP")),上述代码无需修改即可自动为每个货币生成对应行。
内容的提问来源于stack exchange,提问作者AmidOV
相关产品推荐
相关产品推荐

