【问题标题】:How do I compare each column in a table using DataFrame by Scala如何使用 Scala 的 DataFrame 比较表中的每一列
【发布时间】:2017-06-16 17:34:36
【问题描述】:

有两个表;一个是ID表1,另一个是属性表2。

表 1

表 2

如果表 1 中同一行的 ID 具有相同的属性,则我们得到数字 1,否则我们得到 0。最后,我们得到结果表 3。

表 3

例如id1和id2有不同的颜色和大小,所以id1和id2行(表3中的第2行)有“id1 id2 0 0”;

id1和id3颜色相同,大小不同,所以id1和id3行(表3第3行)有“id1 id3 1 0”;

相同的属性---1 不同的属性---0

如何使用 Scala 数据框获得结果表 3?

【问题讨论】:

  • 请更清楚地更新问题。例如颜色列如何从蓝色变为 0 或 1,以及列大小中的 m 如何变为 0 或 1?
  • @RameshMaharjan 我已经详细描述了,你知道怎么做吗?
  • 您的文件中是否有 table1 和 tabel2 的数据?或者它只是问题中的那么多数据?并感谢您的更新。现在很清楚
  • 是的,我的文件与问题中的图片相同。在我的文件中,id1 id2 id3 都是像 id1:12404, id2:3408 这样的数字。你需要这些文件吗?
  • 它们是 csv 格式的吗?

标签: scala apache-spark spark-dataframe


【解决方案1】:

这应该可以解决问题

import spark.implicits._

val t1 = List(
  ("id1","id2"),
  ("id1","id3"),
  ("id2","id3")
).toDF("id_x", "id_y")

val t2 = List(
  ("id1","blue","m"),
  ("id2","red","s"),
  ("id3","blue","s")
).toDF("id", "color", "size")

t1
  .join(t2.as("x"), $"id_x" === $"x.id", "inner")
  .join(t2.as("y"), $"id_y" === $"y.id", "inner")
  .select(
    'id_x,
    'id_y,
    when($"x.color" === $"y.color",1).otherwise(0).alias("color").cast(IntegerType),
    when($"x.size" === $"y.size",1).otherwise(0).alias("size").cast(IntegerType)
  )
  .show()

导致:

+----+----+-----+----+
|id_x|id_y|color|size|
+----+----+-----+----+
| id1| id2|    0|   0|
| id1| id3|    1|   0|
| id2| id3|    0|   1|
+----+----+-----+----+

【讨论】:

  • 非常感谢!我现在拿到桌子了。
  • 嗨。如果我不知道Table2中有多少列怎么办?比如我不知道列名颜色或大小。也许还有另一列叫做品牌。那怎么才能拿到Table3呢?
【解决方案2】:

这里是使用UDF 的方法,它可以帮助您理解代码的重复以及如何最小化代码以提高性能

import spark.implicits._

val df1 = spark.sparkContext.parallelize(Seq(
    ("id1", "id2"),
    ("id1","id3"),
    ("id2","id3")
  )).toDF("idA", "idB")

val df2 = spark.sparkContext.parallelize(Seq(
  ("id1", "blue", "m"),
  ("id2", "red", "s"),
  ("id3", "blue", "s")
)).toDF("id", "color", "size")

val firstJoin = df1.join(df2, df1("idA") === df2("id"), "inner")
  .withColumnRenamed("color", "colorA")
  .withColumnRenamed("size", "sizeA")
  .withColumnRenamed("id", "idx")

val secondJoin = firstJoin.join(df2, firstJoin("idB") === df2("id"), "inner")

val check = udf((v1: String, v2:String ) => {
  if (v1.equalsIgnoreCase(v2)) 1 else 0
})

val result = secondJoin
  .withColumn("color", check(col("colorA"), col("color")))
  .withColumn("size", check(col("sizeA"), col("size")))

val finalResult = result.select("idA", "idB", "color", "size")

希望这会有所帮助!

【讨论】:

  • 谢谢。起初,我试图让它使用 UDF,但我做不到。你的代码对我有帮助!
  • 很高兴知道它有帮助!您可以优化步骤:)
  • 嗨。如果我不知道Table2中有多少列怎么办?比如我不知道列名颜色或大小。也许还有另一列叫做品牌。那怎么才能拿到Table3呢?
  • 可能从df2动态获取所有列标题为List,过滤掉id并在数据集上迭代调用withColumnRenamedwithColumn。可能foldLeft 效果最好
  • 嗨,汤姆·劳斯。你能帮我解决这个问题吗?以下是链接。 stackoverflow.com/questions/44653679/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-18
  • 2017-11-27
相关资源
最近更新 更多