scala中的变量替换

时间:2017-10-17 04:36:57

标签: scala apache-spark dataframe spark-dataframe rdd

我在scala中有两个数据帧,它们都有来自两个不同表但具有相同结构(srcdataframetgttable)的数据。我必须基于复合主键加入这两个,并选择几列并附加两列代码,如下所示:

for(i <- 2 until numCols) {
  srcdataframe.as("A")
    .join(tgttable.as("B"), $"A.INSTANCE_ID" === $"B.INSTANCE_ID" && 
       $"A.CONTRACT_LINE_ID" === $"B.CONTRACT_LINE_ID", "inner")
    .filter($"A." + srcColnm(i) =!= $"B." + srcColnm(i))
    .select($"A.INSTANCE_ID",
            $"A.CONTRACT_LINE_ID",
           "$"+"\""+"A."+srcColnm(i)+"\""+","+"$"+"\""+"B."+srcColnm(i)+"\"")
    .withColumn("MisMatchedCol",lit("\""+srcColnm(i)+"\""))
    .withColumn("LastRunDate",current_timestamp.cast("long"))
    .createOrReplaceTempView("IPF_1M_Mismatch"); 

hiveSQLContext.sql("Insert into table xxxx.f2f_Mismatch1 select t.* from (select * from IPF_1M_Mismatch) t");}

以下是我要做的事情:

  1. 基于srcdataframetgttable的{​​{1}}和instance_id的内部联接。
  2. 仅选择contract_line_idinstance_idcontract_line_idmismatched_col_values的硬编码,mismatched_col_nm
  3. timestampsrcColnm(i)个字符串,其中包含要比较的非主键。
  4. 但是,我无法在for循环中解析数据框内的变量。我尝试查找解决方案herehere。我知道这可能是因为spark只在编译时替换了变量,在这种情况下我不知道如何解决它。

1 个答案:

答案 0 :(得分:1)

您可以简单地使用字符串或$函数,而不是使用col()创建列。我还建议在for之外执行join,因为这是一项昂贵的操作。稍微改变了代码,解决问题的主要区别在于选择:

val df =  srcdataframe.as("A")
  .join(tgttable.as("B"), Seq("INSTANCE_ID", "CONTRACT_LINE_ID"), "inner")

for(columnName <- srcColnm) {
  df.filter(col("A." + columnName) =!= col("B." + columnName))
    .select("INSTANCE_ID", "CONTRACT_LINE_ID", "A." + columnName, "B." + columnName)
    .withColumn("MisMatchedCol", lit(columnName))
    .withColumn("LastRunDate", current_timestamp().cast("long"))
    .createOrReplaceTempView("IPF_1M_Mismatch")

  // Hive command
}

关于select中的问题:

$col()函数的缩写,它按名称在数据框中选择一列。 select中的问题是,为了清楚起见,两个第一个参数col("A.INSTANCE_ID")col("A.CONTRACT_LINE_ID") are two columns ( $ replaced by col()`。

但是,接下来的两个参数是字符串。不可能混合这两个,要么所有参数都应该是列,要么全部都是字符串。使用"A."+srcColnm(i)构建列名$时,无法使用,但您可以使用col("A."+srcColnm(i))