将数据帧写入CSV

时间:2019-04-18 10:48:46

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

因此,我试图读取一个现有文件,将其保存到DataFrame中,一旦完成,我将在该现有DataFrame和我已经创建的新DataFrame之间建立一个“联盟”,两者具有相同的列并共享相同的模式。

由于限制,我也无法给出重要名称,也无法给出任何数据

val dfExist = spark.read.format("csv").option("header", "true").option("delimiter", ",").schema(schema).load(filePathAggregated3) 
val df5 = df4.union(dfExist)

完成后,我得到了“ start_ts”(Epoch格式的时间戳),它在上述数据帧(df4和dfExist)之间的联合中是重复的,而且我摆脱了一些我不想要的字符

val df6 = df5.select($"start_ts").collect()
val df7 = df6.diff(df6.distinct).distinct.mkString.replace("[", "").replace("]", "")

现在,我使用此“ start_ts”重复项来过滤DataFrame并创建2个新DataFrame,以选择此重复时间戳的项以及与该重复时间戳不同的项

val itemsNotDup = df5.filter(!$"start_ts".like(df7)).select($"start_ts",$"avg_value",$"Number_of_val")
val items = df5.filter($"start_ts".like(df7)).select($"start_ts",$"avg_value",$"Number_of_val")

然后我将avg_value和Number_of_values保存在2个不同的列表中

items.map(t => t.getAs[Double]("avg_value")).collect().foreach(saveList => listDataDF += saveList.toString)
items.map(t => t.getAs[Long]("Number_of_val")).collect().foreach(saveList => listDataDF2 += saveList.toString)

现在,我使用列表中的值进行一些数学运算(这是我要查找的问题所在的地方)

val newAvg = ((listDataDF(0).toDouble*listDataDF2(0).toDouble) - (listDataDF(1).toDouble*listDataDF2(1).toDouble)) / (listDataDF2(0) + listDataDF2(1)).toInt
val newNumberOfValues = listDataDF2(0).toDouble + listDataDF2(1).toDouble

然后将重复的时间戳记(df7),平均值和值的数量保存为一个列表,作为一个单独的列表,此列表转换为一个DataFrame,然后转换为一个新的DataFrame,其中的列应该是

listDataDF3 += df7 + ',' + newAvg.toString + ',' + newNumberOfValues.toString + ','
val listDF = listDataDF3.toDF("value")
val listDF2 = listDF.withColumn("_tmp", split($"value", "\\,")).select(
            $"_tmp".getItem(0).as("start_ts"),
            $"_tmp".getItem(1).as("avg_value"),
            $"_tmp".getItem(2).as("Number_of_val")
          ).drop("_tmp")

最后,我将没有重复项的DataFrame与新的DataFrame合并,新的DataFrame具有重复的时间戳记,重复的平均值和平均值以及值的数量之和。

val finalDF = itemsNotDup.union(listDF2)
finalDF.coalesce(1).write.mode(SaveMode.Overwrite).format("csv").option("header","true").save(filePathAggregated3)

当我在SPARK中运行此代码时,它给了我错误,我认为它与空列表有关(因为使用列表的值进行一些数学运算时会给我错误),但是如果我删除了我写入CSV时,代码可以完美运行,我也将数学计算的列表和值保存到文件中,而且它们不为空。

我的假设是,在读取文件之前将其删除(由于spark如何在工作人员之间分配任务),这就是为什么列表为空的原因,因此在尝试使用这些值进行数学运算时出现此错误。 / p>

我正在尝试尽可能清晰,但我无法提供更多细节,也无法显示任何输出。

那么,如何避免此错误?而且我只有一个月使用scala / spark,所以任何代码建议也都很好。

谢谢。

2 个答案:

答案 0 :(得分:0)

此错误是由于数据引起的。您的任何列表都不包含预期的列。当您引用该索引时,列表会为您提供此错误

答案 1 :(得分:0)

这是与读取文件有关的问题,我进行了检查(df.rdd.isEmpty),并且DF是否为空,我得到了此错误。将此作为if / else语句来检查DF是否为空,现在可以正常工作了。