我可以递归地将变换应用于scala中的Spark数据帧吗?

时间:2017-04-23 10:04:51

标签: scala apache-spark apache-spark-sql

使用union构建一个适当大的测试数据集。这没关系:

val df = spark.read.json("/opt/spark/examples/src/main/resources/people.json") df.union(df).union(df).count() 但是我想做这样的事情: val df = spark.read.json("/opt/spark/examples/src/main/resources/people.json") for (a <- 1 until 10){ df = df.union(df) } barfs有错误 <console>:27: error: reassignment to val df = df.union(df) ^ 我知道这种技术可以使用python,但这是我第一次使用scala,所以我不确定语法。

如何递归地将数据帧与 n 时间联合起来?

2 个答案:

答案 0 :(得分:2)

如果在数据集上使用val,它将成为一个不可变的变量。这意味着您无法进行任何重新分配。如果您将定义更改为var df,则代码应该有效。

没有可变数据的功能方法是:

val df = List(1,2,3,4,5).toDF
val bigDf = ( for (a <- 1 until 10) yield df ) reduce (_ union _)

for循环将创建一个包含DataFrame的指定长度的IndexedSeq,reduce函数将第一个DataFrame与第二个结合起来,并将使用结果重新开始。

没有for循环就更短了:

val df = List(1,2,3,4,5).toDF
val bigDf = 1 until 10 map (_ => df) reduce (_ union _)

答案 1 :(得分:0)

您也可以使用任意范围的尾递归来执行此操作:

@tailrec
def bigUnion(rng: Range, df: DataFrame): DataFrame = {
  if (rng.isEmpty) df
  else bigUnion(rng.tail, df.union(df))
}
val resultingBigDF = bigUnion(1.to(10), myDataFrame)

请注意,这是基于我所做过的类似事情的未经测试的代码。