Как получить количество строк в результате объединения в Spark - PullRequest
1 голос
/ 05 ноября 2019

Рассмотрим эти два кадра данных:

+---+
|id |
+---+
|1  |
|2  |
|3  |
+---+


+---+-----+
|idz|word |
+---+-----+
|1  |bat  |
|1  |mouse|
|2  |horse|
+---+-----+

Я делаю Left join on ID=IDZ:

val r = df1.join(df2, (df1("id") === df2("idz")), "left_outer").
      withColumn("ID_EMPLOYE_VENDEUR", when(col("word") =!= ("null"), col("word")).otherwise(null)).drop("word")

r.show(false)

+---+----+------------------+
|id |idz |ID_EMPLOYE_VENDEUR|
+---+----+------------------+
|1  |1   |mouse             |
|1  |1   |bat               |
|2  |2   |horse             |
|3  |null|null              |
+---+----+------------------+

Но что, если я хочу сохранить только те строки, чей идентификатор имеет только одинIDZ? Если нет, я бы хотел иметь значение NULL в ID_EMPLOYE_VENDEUR. Желаемый результат:

+---+----+------------------+
|id |idz |ID_EMPLOYE_VENDEUR|
+---+----+------------------+
|1  |1   |null              | --Because the Join resulted two different lines
|2  |2   |horse             |
|3  |null|null              |
+---+----+------------------+

Я должен точно указать, что я работаю над большим DF. Решение должно быть не очень дорогим по времени.

Спасибо

Ответы [ 2 ]

1 голос
/ 05 ноября 2019

Согласно упомянутым вами данным, ваши данные слишком велики, поэтому groupBy не подходит для группировки данных и присоединения к функции Windows over , как показано ниже:

import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions._

def windowSpec = Window.partitionBy("idz")

val newDF = df1.withColumn("count", count("idz").over(windowSpec)).dropDuplicates("idz").withColumn("word", when(col("count") >=2 , lit(null)).otherwise(col("word"))).drop("count")

val r = df1.join(newDF, (df1("id") === newDF("idz")), "left_outer").withColumn("ID_EMPLOYE_VENDEUR", when(col("word") =!= ("null"), col("word")).otherwise(null)).drop("word") 
 r show 
+---+----+------------------+
| id| idz|ID_EMPLOYE_VENDEUR|
+---+----+------------------+
|  1|   1|              null|
|  3|null|              null|
|  2|   2|             horse|
+---+----+------------------+
1 голос
/ 05 ноября 2019

Вы можете легко получить информацию о том, что более двух df2 idz совпало с одним df1 id с groupBy и объединением.

r.join(
    r.groupBy("id").count().as("g"),
    $"g.id" === r("id")
  )
  .withColumn(
    "ID_EMPLOYE_VENDEUR",
    expr("if(count != 1, null, ID_EMPLOYE_VENDEUR)")
  )
  .drop($"g.id").drop("count")
  .distinct()
  .show()

Примечание: И groupBy, и объединение не вызывают какого-либо дополнительного шага обмена (перемешивание по сети), поскольку кадр данных r уже разбит на разделына id (потому что это результат соединения на id).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...