显示/计数时出现火花冲洗数据框

时间:2019-03-06 17:29:34

标签: scala apache-spark

我试图先打印一个数据帧的计数,然后打印它的前几行,然后再将其发送出去进行进一步处理。

奇怪的是,在调用count()之后,数据帧为空。

val modifiedDF = funcA(sparkDF)
val deltaDF = modifiedDF.except(sparkDF)
println(deltaDF.count()) // prints 10
println(deltaDF.count())  //prints 0, similar behavior with show  
funcB(deltaDF) //gets null dataframe

我能够使用deltaDF.collect.foreach(println)和随后对count的调用来验证相同的内容。

但是,如果我不打电话给countshow,而是直接发送它,funcB将获得10行的整个DF。

是预期的吗?

funcA()的定义及其依赖性:

def funcA(inputDataframe: DataFrame): DataFrame = {
    val col_name = "colA"
    val modified_df = inputDataframe.withColumn(col_name, customUDF(col(col_name)))
    val modifiedDFRaw = modified_df.limit(10)
    modifiedDFRaw.withColumn("colA", modifiedDFRaw.col("colA").cast("decimal(38,10)"))
}


val customUDF = udf[Option[java.math.BigDecimal], java.math.BigDecimal](myUDF)


def myUDF(sval: java.math.BigDecimal): Option[java.math.BigDecimal] = {
        val strg_name = Option(sval).getOrElse(return None)
        if (change_cnt < 20)  { 
                    change_cnt = change_cnt + 1
                     Some(strg_name.multiply(new java.math.BigDecimal("1000")))
        } else {
            Some(strg_name)
        } 
    }

2 个答案:

答案 0 :(得分:1)

首先,用作UserDefinedFunction的函数必须至少是幂等的,但必须是纯函数。否则,结果将是不确定的。尽管在最新版本中提供了一些逃生功能(可能会提示Spark不应该重新执行该功能),但这些操作在这里没有帮助。

此外,它具有可变的稳定性(尚不清楚change_cnt的来源是什么,但是它是在udf中写入和读取的),只是行不通-Spark doesn't provide global mutable state

总体代码:

  • 修改某些对象的某些本地副本。
  • 根据此类对象做出决定。

不幸的是,这两个组成部分都无法挽救。您必须回到计划阶段并重新考虑您的设计。

答案 1 :(得分:0)

您的数据框是一个分布式数据集,由于每个节点中的count()可能不同,因此尝试执行count()会返回不可预测的结果。阅读下面有关RDD的文档。它也适用于DataFrame。

https://spark.apache.org/docs/2.3.0/rdd-programming-guide.html#understanding-closures- https://spark.apache.org/docs/2.3.0/rdd-programming-guide.html#printing-elements-of-an-rdd