Scala:如何在for循环外部循环块中使用变量

时间:2016-12-07 02:34:31

标签: scala for-loop apache-spark scope spark-dataframe

如何使用我的所有json文件创建Dataframe,在阅读每个文件后,我需要将fileName添加为dataframe中的字段?似乎for循环中的变量在循环外部无法识别。如何克服这个问题?

for (jsonfilenames <- fileArray) {
      var df = hivecontext.read.json(jsonfilename)
      var tblLanding = df.withColumn("source_file_name", lit(jsonfilename))

    }

   // trying to create temp table from dataframe created in loop

tblLanding.registerTempTable("LandingTable") // ERROR here, can't resolved tblLanding

提前谢谢你 侯塞因

2 个答案:

答案 0 :(得分:2)

我认为你是编程本身的新手。 无论如何你去。

基本上你指定类型并在循环之前初始化它。

var df:DataFrame = null
for (jsonfilename <- fileArray) {
      df = hivecontext.read.json(jsonfilename)
      var tblLanding = df.withColumn("source_file_name", lit(jsonfilename))

    }

df.registerTempTable("LandingTable") // Getting ERROR here

<强>更新

好的,你是编程的新手,甚至是循环。

假设fileArray的值为[1.json,2.json,3.json,4.json]

因此,循环实际上通过读取4个json文件创建了4个数据帧。 你要将哪一个注册为临时表。

如果全部,

var df:DataFrame = null
var count = 0
for (jsonfilename <- fileArray) {
      df = hivecontext.read.json(jsonfilename)
      var tblLanding = df.withColumn("source_file_name", lit(jsonfilename))
      df.registerTempTable(s"LandingTable_$count")
      count++;
    }

在此更新之前df为空的原因是,fileArray为空或Spark无法读取该文件。打印并检查。

查询任何已注册的LandingTable

val df2 = hiveContext.sql("SELECT * FROM LandingTable_0")

<强>更新 问题已更改为从所有json文件生成单个dataFrame。

var dataFrame:DataFrame = null
for (jsonfilename <- fileArray) {
   val eachDataFrame = hivecontext.read.json(jsonfilename)
   if(dataFrame == null)
      dataFrame = eachDataFrame
   else
      dataFrame = eachDataFrame.unionAll(dataFrame)
}
dataFrame.registerTempTable("LandingTable")

确保,fileArray不为空,fileArray中的所有json文件都具有相同的架构。

答案 1 :(得分:0)

// Create list of dataframes with source-file-names
val dfList = fileArray.map{ filename =>
  hivecontext.read.json(filename)
             .withColumn("source_file_name", lit(filename))
}

// union the dataframes (assuming all are same schema)
val df = dfList.reduce(_ unionAll _)  // or use union if spark 2.x

// register as table
df.registerTempTable("LandingTable")