【问题标题】:Spark (scala) dataframes - Check whether strings in column exist in a column of another dataframeSpark(scala)数据框 - 检查列中的字符串是否存在于另一个数据框的列中
【发布时间】:2019-11-30 15:26:53
【问题描述】:

我有一个 spark 数据框,我希望检查特定列中的每个字符串是否存在于另一个数据框的预定义列中。 我在Spark (scala) dataframes - Check whether strings in column contain any items from a set 发现了同样的问题

但我想检查列中的字符串是否存在于另一个数据框的列中,而不是列表或集合遵循该问题。谁能帮我!我不知道将列转换为集合或列表,也不知道数据框中的“存在”方法。

我的数据与此类似

df1:

    +---+-----------------+
    | id|      url        |
    +---+-----------------+
    |  1|google.com       |
    |  2|facebook.com     |
    |  3|github.com       |
    |  4|stackoverflow.com|
    +---+-----------------+

df2:

    +-----+------------+
    | id  | urldetail  |
    +-----+------------+
    |  11 |google.com  |
    |  12 |yahoo.com   |
    |  13 |facebook.com|
    |  14 |twitter.com |
    |  15 |youtube.com |
    +-----+------------+

现在,我正在尝试使用比较结果创建第三列,以查看 $"urldetail" 列中的字符串是否存在于 $"url" 中

    +---+------------+-------------+
    | id|  urldetail |   check     | 
    +---+------------+-------------+
    | 11|google.com  |        1    |     
    | 12|yahoo.com   |        0    |
    | 13|facebook.com|        1    |
    | 14|twitter.com |        0    |
    | 15|youtube.com |        0    |
    +---+------------+-------------+

我想使用UDF,但我不知道如何检查字符串是否存在于数据框的列中!请帮我!

【问题讨论】:

  • 欢迎来到 SO !我建议您阅读:stackoverflow.com/help/minimal-reproducible-examplestackoverflow.com/help/how-to-ask。我也建议你添加inputsoutputs
  • @Hiệp Bạch 如果您的数据看起来像这样,只需加入每个 DataFrame 的字符串列。如果df2的字符串列是一个包含多个单词的字符串,那就有点复杂了。
  • 我仍然无法加入他们。能给我一些代码吗?
  • 我必须做很多努力,因为你还没有把数据放在第一位下一篇请注意..
  • 对不起,我是新用户,所以我的问题还不清楚。你的回答很有帮助,但我没有找到想要的结果:(

标签: scala dataframe apache-spark


【解决方案1】:

我有一个 spark 数据框,我希望检查每个字符串是否在 特定列包含来自预定义 a 的任意数量的单词 另一个数据框的列。

这是方法。使用=like

package examples

import org.apache.log4j.Level
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions.{col, _}

object CompareColumns extends App {
  val logger = org.apache.log4j.Logger.getLogger("org")
  logger.setLevel(Level.WARN)
  val spark = SparkSession.builder()
    .appName(this.getClass.getName)
    .config("spark.master", "local").getOrCreate()

  import spark.implicits._

  val df1 = Seq(

    (1, "google.com"),
    (2, "facebook.com"),
    (3, "github.com"),
    (4, "stackoverflow.com")).toDF("id", "url").as("first")
  df1.show
  val df2 = Seq(
    (11, "google.com"),
    (12, "yahoo.com"),
    (13, "facebook.com"),
    (14, "twitter.com")).toDF("id", "url").as("second")
  df2.show
  val df3 = df2.join(df1, expr("first.url  like  second.url"), "full_outer").select(
    col("first.url")
    , col("first.url").contains(col("second.url")).as("check")).filter("url is not null")
  df3.na.fill(Map("check" -> false))
    .show


}



结果:

+---+------------------+ |编号|网址| +---+------------------+ | 1| google.com| | 2|脸书网| | 3| github.com| | 4|stackoverflow.com| +---+------------------+ +---+------------+ |编号|网址| +---+------------+ | 11| google.com| | 12|雅虎网| | 13|facebook.com| | 14|推特网| +---+------------+ +-----------------+-----+ |网址|检查| +-----------------+-----+ | google.com|是的| |脸书网|是的| | github.com|假| |stackoverflow.com|假| +-----------------+-----+

通过完全外部连接,我们可以实现这一点... 更多详情see my article with all joins here in my linked in post

注意:我使用布尔值代替 0 表示假 1 表示真 这里的条件..您可以将它们翻译成您想要的任何内容...

UPDATE :如果第二个数据帧中的行增加 你可以使用它,它不会错过任何第二行

val df3 = df2.join(df1, expr("first.url  like  second.url"), "full").select(
    col("second.*")
    , col("first.url").contains(col("second.url")).as("check"))
    .filter("url is not null")
  df3.na.fill(Map("check" -> false))
    .show

另外,你可以试试regexp_extract,如下图所示

https://stackoverflow.com/a/53880542/647053

【讨论】:

  • 2个df的ID不同;所以我不能加入他们:(
  • 是的,在上次加入时我没有使用 id 列加入。请检查。这里的一个问题是,如果连接中的字符串不匹配,那么它可能会导致 x 产品
  • 我的数据有问题,我已经编辑了我的帖子。当我加入时,很多字符串不匹配! :( 和 2 个 dfs 的大小不同
  • 我想要所有行的结果,因为我的目标是字符串的结果为假
  • 老大!这是您提供的数据,并且做得非常接近。采取这个并根据您的需要进行修改。方法是一样的
【解决方案2】:

读取您的数据并使用修剪操作只是为了在加入字符串以删除空白时保持保守

val df= Seq((1,"google.com"), (2,"facebook.com"), ( 3,"github.com "), (4,"stackoverflow.com")).toDF("id", "url").select($"id", trim($"url").as("url"))    


val df2   =Seq(( 11 ,"google.com"), (12 ,"yahoo.com"), (13 ,"facebook.com"),(14 ,"twitter.com"),(15,"youtube.com")).toDF( "id" ,"urldetail").select($"id", trim($"urldetail").as("urldetail")) 


df.join(df2.withColumn("flag", lit(1)).drop("id"), (df("url")===df2("urldetail")), "left_outer").withColumn("contains_bool",
    when($"flag"===1, true) otherwise(false)).drop("flag","urldetail").show


+---+-----------------+-------------+
| id|              url|contains_bool|
+---+-----------------+-------------+
|  1|       google.com|         true|
|  2|     facebook.com|         true|
|  3|       github.com|        false|
|  4|stackoverflow.com|        false|
+---+-----------------+-------------+

【讨论】:

  • 为什么要拆分??除了 2 DF 的 ID 不同,所以我不能加入它们。我使用的是 Spark 版本 2.3.x,所以我想使用 udf,但我不知道如何检查字符串是否存在于数据框的列中。 :(
  • @Hiệp Bạch 您需要明确说明您的数据是什么样的。如果 ID 不同,则必须考虑许多其他问题。
猜你喜欢
  • 1970-01-01
  • 2021-09-06
  • 2022-01-18
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 2023-03-10
  • 1970-01-01
相关资源
最近更新 更多