【问题标题】:pyspark v 1.6 dataframe no left anti join?pyspark v 1.6 数据框没有左反连接?
【发布时间】:2020-03-25 19:33:21
【问题描述】:

也许我完全误解了事情,但基本上有 2 个 dfs,我不想得到 df1 中不在 df2 中的所有行,我认为这是左反连接会做的事情,显然pyspark v1.6 不支持?

df1:

+----+---+
| id | x |
+----+---+
| 1  | a |
| 2  | b |
| 3  | c |
| 4  | d |
+----+---+

df2:

+----+---+
| id | x |
+----+---+
| 1  | a |
| 2  | b |
+----+---+

desired output df3:

+----+---+
| id | x |
+----+---+
| 3  | c |
| 4  | d |
+----+---+

我正在尝试:

df3 = df1.where(~col("id").isin(df2["id"]))

这给了我 .count() of 0 行

和:

df3 = df1.join(df2, on = ["id"], how = "leftanti")

为此,我得到以下异常:

IllegalArgumentException: u"Unsupported join type 'leftanti'. Supported join types include: 'inner', 'outer', 'full', 'fullouter', 'leftouter', 'left', 'rightouter', 'right', 'leftsemi'."

感谢您的帮助。

【问题讨论】:

    标签: python dataframe apache-spark join pyspark


    【解决方案1】:

    我们可以模仿 leftanti 加入 left join 并仅过滤来自 df2 中 id 的空列。

    Example:

    df1.alias("a").join(df2.alias("b"),col("a.id") == col("b.id"),"left").filter("b.id is null").select("a.*").show()
    #+---+---+
    #| id|  x|
    #+---+---+
    #|  3|  c|
    #|  4|  d|
    #+---+---+
    

    从 Spark2.4+ 开始,我们可以使用 exceptAll 函数来处理这种情况:

    df1.exceptAll(df2).show()
    
    #+---+---+
    #| id|  x|
    #+---+---+
    #|  3|  c|
    #|  4|  d|
    #+---+---+
    

    【讨论】:

      【解决方案2】:

      我很喜欢 @Shu 对 Spark 1.6 的回答(不幸的是,它仍在许多遗留系统中使用)并且我将它概括为进一步使用,如果有人需要它:

      def subtractByKey(df1, df2, key):
          return (df1.alias("a").join(df2.alias("b"), on=F.col("a.{key}".format(key=key)) == F.col("b.{key}".format(key=key)), how="left")
                  .where("b.{key} IS NULL".format(key=key))
                  ).select("a.*")
      

      在最近的 Spark 版本中也可以达到相同的行为

      df1.join(df2, on=key, how="left_anti")

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-24
        • 2018-01-31
        • 2021-09-25
        • 2018-03-18
        • 1970-01-01
        • 2012-12-06
        相关资源
        最近更新 更多