【问题标题】:PySpark Dataframes: Full Outer Join with a conditionPySpark Dataframes:带条件的完全外连接
【发布时间】:2020-03-17 00:14:44
【问题描述】:

我有以下 2 个数据框-

dataframe_a
+----------------+---------------+
|         user_id|         domain|
+----------------+---------------+
|            josh|     wanadoo.fr|
|        samantha|     randomn.fr|
|             bob|    eidsiva.net|
|           dylan|    vodafone.it|
+----------------+---------------+

dataframe_b
+----------------+---------------+
|         user_id|         domain|
+----------------+---------------+
|            josh|  oldwebsite.fr|
|        samantha|     randomn.fr|
|           dylan|      oldweb.it|
|            ryan|      chicks.it|
+----------------+---------------+

我想做一个完整的外部联接,但保留dataframe_a 的domain 列中的值,以防我为单个user_id 获得2 个不同的域。所以,我想要的数据框看起来像-

desired_df
+----------------+---------------+
|         user_id|         domain|
+----------------+---------------+
|            josh|     wanadoo.fr|
|        samantha|     randomn.fr|
|             bob|    eidsiva.net|
|           dylan|    vodafone.it|
|            ryan|      chicks.it|
+----------------+---------------+

我想我可以做一些类似的事情-

desired_df = dataframe_a.join(dataframe_b, ["user_id"], how="full_outer").drop(dataframe_b.domain)

但我担心这是否会在我想要的数据框中给我ryan。这是正确的方法吗?

【问题讨论】:

    标签: python python-3.x dataframe pyspark pyspark-dataframes


    【解决方案1】:

    你会想要使用'coalesce'。在您当前的解决方案中,ryan 将位于结果数据框中,但剩余的 dataframe_a.domain 列的值为空。

    joined_df = dataframe_a.join(dataframe_b, ["user_id"], how="full_outer")
    
    +----------------+---------------+---------------+
    |         user_id|         domain|         domain|
    +----------------+---------------+---------------+
    |            josh|     wanadoo.fr|  oldwebsite.fr|
    |        samantha|     randomn.fr|     randomn.fr|
    |             bob|    eidsiva.net|               |
    |           dylan|    vodafone.it|      oldweb.it|
    |            ryan|               |      chicks.it|
    +----------------+---------------+---------------+
    

    'coalesce' 允许您指定偏好顺序,但会跳过空值。

    import pyspark.sql.functions as F
    joined_df = joined_df.withColumn(
      "preferred_domain",
      F.coalesce(dataframe_a.domain, dataframe_b.domain)
    )
    joined_df = joined_df.drop(dataframe_a.domain).drop(dataframe_b.domain)
    

    给予

    +----------------+----------------+
    |         user_id|preferred_domain|
    +----------------+----------------+
    |            josh|      wanadoo.fr|
    |        samantha|      randomn.fr|
    |             bob|     eidsiva.net|
    |           dylan|     vodafone.it|
    |            ryan|       chicks.it|
    +----------------+----------------+
    

    【讨论】:

    • 这是一个很好的答案。 (1)这是做我想做的唯一/最快的方法吗? (2) coalesce 步骤可以和join 语句一起执行,还是我总是需要做你写的3个步骤?
    • 也可以一步完成,但执行起来不会有任何区别。我猜.. :-) stackoverflow.com/questions/53587175/…
    • 您不能在加入过程中执行此操作。您可以使用链接将其作为同一行的一部分进行。但是,它们在语义上是完全相同的。 Spark 构建了一组操作来在数据集上执行,然后在必要时一次优化并执行它们。将操作放在一条链式的线上与像我一样按顺序分配并没有什么不同。通常该执行发生在“显示”或“写入”操作上。
    • @JoeyLesh 是的,只是询问链接语法的外观,如果没有其他方法可以作为join 的一部分。 @vikrantrana 的链接显示了它。
    【解决方案2】:

    不,执行 full_outer 连接将留下所需的数据帧,其中与 ryan 对应的域名为空值。上述给定数据帧上的任何类型的连接操作都不会为您提供所需的输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 2012-01-06
      • 2013-03-11
      相关资源
      最近更新 更多