因此,我试图读取一个现有文件,将其保存到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,所以任何代码建议也都很好。
谢谢。
答案 0 :(得分:0)
此错误是由于数据引起的。您的任何列表都不包含预期的列。当您引用该索引时,列表会为您提供此错误
答案 1 :(得分:0)
这是与读取文件有关的问题,我进行了检查(df.rdd.isEmpty),并且DF是否为空,我得到了此错误。将此作为if / else语句来检查DF是否为空,现在可以正常工作了。