【问题标题】:Join the dataframe if value of one column exists as substring in another dataframe如果一列的值作为子字符串存在于另一个数据框中,则加入数据框
【发布时间】:2022-10-24 15:16:25
【问题描述】:

我有一个像这样的数据框df1

和另一个数据框df2 像这样:

如何使用左连接将df2df1 连接起来,以便我的输出如下所示?

【问题讨论】:

    标签: apache-spark join pyspark substring left-join


    【解决方案1】:

    在加入之前,您可以在 df1explode 中使用 split 值。

    df3 = df1.withColumn('Value', F.explode(F.split('Value', ';')))
    df4 = df2.join(df3, 'Value', 'left')
    

    完整示例:

    from pyspark.sql import functions as F
    df1 = spark.createDataFrame([('apple;banana', 150), ('carrot', 20)], ['Value', 'Amount'])
    df2 = spark.createDataFrame([('apple',), ('orange',)], ['Value'])
    
    df3 = df1.withColumn('Value', F.explode(F.split('Value', ';')))
    df4 = df2.join(df3, 'Value', 'left')
    
    df4.show()
    # +------+------+
    # | Value|Amount|
    # +------+------+
    # | apple|   150|
    # |orange|  null|
    # +------+------+
    

    处理空值。如果您想要成功加入的两个数据框中的“值”列中有空值,则需要使用eqNullSafe 相等。使用此条件通常会在输出数据框中保留两个数据框中的“值”列。所以要明确删除它,我建议在数据帧上使用alias

    from pyspark.sql import functions as F
    df1 = spark.createDataFrame([('apple;banana', 150), (None, 20)], ['Value', 'Amount'])
    df2 = spark.createDataFrame([('apple',), ('orange',), (None,)], ['Value'])
    
    df3 = df1.withColumn('Value', F.explode(F.coalesce(F.split('Value', ';'), F.array(F.lit(None)))))
    df4 = df2.alias('a').join(
        df3.alias('b'),
        df2.Value.eqNullSafe(df3.Value),
        'left'
    ).drop(F.col('b.Value'))
    
    df4.show()
    # +------+------+
    # | Value|Amount|
    # +------+------+
    # | apple|   150|
    # |  null|    20|
    # |orange|  null|
    # +------+------+
    

    【讨论】:

    • 嗨@ZygD,感谢您的回答。当列不为空时它起作用。如果该列为空,如何执行爆炸?
    • 嗨 ZygD,数据框 df1 中的值列有时可能为空。那怎么爆?
    • 我已经用两个数据帧中都有空值并且你想成功加入它们的情况更新了答案。仅在一个数据框中具有 null 不需要该方法 - 第一个选项连接得很好。
    【解决方案2】:

    在左外连接中使用 SQL “like”运算符。 尝试这个

    //Input
    
    spark.sql(" select 'apple;banana' value,  150 amount union all  select 'carrot', 50 ").createOrReplaceTempView("df1")
    spark.sql(" select 'apple' value union all  select 'orange' ").createOrReplaceTempView("df2")
    
    //Output
    
    spark.sql("""
    select a.value, b.amount 
       from df2 a 
       left join df1 b 
       on ';'||b.value||';' like '%;'||a.value||';%' 
    """).show(false)
    
    +------+------+
    |value |amount|
    +------+------+
    |apple |150   |
    |orange|null  |
    +------+------+
    

    【讨论】:

      猜你喜欢
      • 2021-01-22
      • 2019-08-14
      • 1970-01-01
      • 1970-01-01
      • 2021-01-28
      • 1970-01-01
      • 2023-02-07
      • 2021-07-28
      • 2021-01-16
      相关资源
      最近更新 更多