Scala代码根据另一个数据帧标记数据帧行

时间:2017-05-30 09:31:05

标签: scala apache-spark spark-dataframe

我刚刚开始学习scala来进行数据分析,当我尝试根据另一个数据框标记数据行时遇到了问题。

假设我有一个df1"date","id","value","label",对于"F"中的所有行,它们都设置为df1。然后我有df2这是一组包含"date","id","value"列的较小数据。然后我想将df1中的行标签从"F"更改为"T"df2中,df2中的iesome行与("date","id","value")中的行df1具有相同的组合。

我尝试使用df.filterdf.join,但似乎两者都无法解决我的问题。

2 个答案:

答案 0 :(得分:0)

基本思想是加入两者然后计算结果。像这样:

df2Mod = df2.withColumn("tmp", lit(true))
joined = df1.join(df2Mod , df1("date") <=> df2Mod ("date") && df1("id") <=> df2Mod("id") && df1("value") <=> df2Mod("value"), "left_outer")
joined.withColumn("label", when(joined("tmp").isNull, "F").otherwise("T")

我们的想法是添加&#34; tmp&#34;列然后执行left_outer连接。 &#34; TMP&#34;对于不在df2中的所有内容都将为null,因此我们可以使用它来计算标签。

答案 1 :(得分:0)

我认为这就是你要找的东西。

val spark =SparkSession.builder().master("local").appName("test").getOrCreate()

import spark.implicits._
      //create Dataframe 1
    val df1 = spark.sparkContext.parallelize(Seq(
      ("2016-01-01", 1, "abcd", "F"),
      ("2016-01-01", 2, "efg", "F"),
      ("2016-01-01", 3, "hij", "F"),
      ("2016-01-01", 4, "klm", "F")
    )).toDF("date","id","value", "label")

  //Create Dataframe 2
  val df2 = spark.sparkContext.parallelize(Seq(
    ("2016-01-01", 1, "abcd"),
    ("2016-01-01", 3, "hij")
  )).toDF("date1","id1","value1")

  val condition = $"date" === $"date1" && $"id" === $"id1" && $"value" === $"value1"

  //Join two dataframe with above condition
  val result = df1.join(df2, condition, "left")

//  check wather both fields contain same value and drop columns 
  val finalResult = result.withColumn("label", condition)
    .drop("date1","id1","value1")
//Update column label from true false to T or F
  finalResult.withColumn("label", when(col("label") === true, "T").otherwise("F")).show