簡體   English   中英

Spark-scala Join 的問題。 尋找更好的方法

[英]Issue with Spark-scala Join . Looking for a better Approach

我有 2 個 DF,如下所示。

+---+---+---+
|  M| c2| c3|
+---+---+---+
|  1|  2|  3|
|  2|  3|  4|
+---+---+---+

+---+---+---+
|  M| c2| c3|
+---+---+---+
|  1| 20| 30|
|  2| 30| 40|
+---+---+---+

獲得如下新數據框的最佳方法應該是什么。這意味着,新的 Df 具有列名 c2 和 c3,但值是concat( df1("c1"),df1("c2") )但具有相同的列名.我可以用df3.withColumn("c2_new",concat( df1("c2"),df2("c2") ))做到這一點,然后將新列重命名為 C2。 但問題是我的 DF 中有 150 多個列。這里最好的方法是什么?

+---+------+-----+
|  M| c2  |   c3 |
+---+-----+------+
|  1| 2_20|  3_30|
|  2| 3_30|  4_40|
+---+------+-----+

如果您有很寬的列,則可以遍歷列並對其應用相同的轉換。 在您的情況下,您應該像這樣合並數據框和聚合列:

import org.apache.spark.sql.types.StringType

val commonColumns = (df1.columns.toSet & df2.columns.toSet).filter(_ != "M").toSeq
commonColumns

df1.union(df2)
    .groupBy("M")
    .agg(count(lit(1)) as "cnt", 
        commonColumns.map(c => concat_ws("_", collect_set(col(c).cast(StringType))) as c):_*)
    .select("M", commonColumns:_*)
        .show

這是輸出:

+---+----+----+
|  M|  c2|  c3|
+---+----+----+
|  1|20_2|3_30|
|  2|3_30|40_4|
+---+----+----+

如果您對排序有要求(即來自df1值必須在左側,來自df2值必須在右側),您可以使用以下技巧:

  1. union之前添加日期幀編號( 12 )作為新列
  2. 從數據框編號和列值創建結構
  3. 在聚合期間取這個結構的minmax
  4. 從結構中提取值
  5. 帶下划線的連接值

代碼:

df1
    .withColumn("src", lit(1))
    .union(df2.withColumn("src", lit(2)))
    .groupBy("M")
    .agg(count(lit(1)) as "cnt", 
        commonColumns.map(c => concat(
            min(struct($"src", col(c)))(c),
            lit("_"),
            max(struct($"src", col(c)))(c)) as c):_*)
    .select("M", commonColumns:_*)
    .show

最終結果排序:

+---+----+----+
|  M|  c2|  c3|
+---+----+----+
|  1|2_20|3_30|
|  2|3_30|4_40|
+---+----+----+

您可以通過連接來做到這一點:

val selectExpr = df1.columns.filterNot(_=="M").map(c => concat_ws("_",df1(c),df2(c)).as(c))

df1.join(df2,"M")
  .select((col("M") +: selectExpr):_*)
  .show()

給出:

---+----+----+
|  M|  c2|  c3|
+---+----+----+
|  1|2_20|3_30|
|  2|3_30|4_40|
+---+----+----+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM