字符串列包含通过 spark scala 精确匹配的单词
Posted
技术标签:
【中文标题】字符串列包含通过 spark scala 精确匹配的单词【英文标题】:String column contains exact matching words through spark scala 【发布时间】:2021-05-15 22:12:51 【问题描述】:我有两个数据框,第一个包含实际数据(从 CSV 文件读取),第二个包含一个包含多个关键字的列。 即下面的 Dataframe-1 相似(我们必须在哪里搜索):
Dataframe-2:
我想要的输出:
我在这里使用 spark scala。我想要从 dataframe-1 中的 dataframe-2 精确匹配单词。我使用了like、rlike、contains等函数,但它没有给我想要的输出。谁能知道如何在 spark scala SQL 中开发此逻辑或使用数据帧的 spark scala 函数。请帮我解决这个问题。
【问题讨论】:
【参考方案1】:您可以通过regexp_replace
在Regex
条件上加入两个DataFrame,如下所示:
val df1 = Seq(
(1, "Test1", "Amount paid to User1 dt"),
(2, "Test2", "Amount paid to User1 dt"),
(3, "Test3", "Amount paid to balamurugan dt"),
(4, "Test4", "Amount paid to final dt"),
(5, "Test5", "Amount paid to John less dt")
).toDF("ID", "Name", "Text")
val df2 = Seq("User1", "murugan", "Amo").toDF("Text")
val pattern = concat(lit("\\b"), df2("Text"), lit("\\b"))
df1.join(df2, regexp_replace(df1("Text"), pattern, lit("")) =!= df1("Text")).show
// +---+-----+-----------------------+-----+
// |ID |Name |Text |Text |
// +---+-----+-----------------------+-----+
// |1 |Test1|Amount paid to User1 dt|User1|
// |2 |Test2|Amount paid to User1 dt|User1|
// +---+-----+-----------------------+-----+
请注意,\b
表示单词边界,因此将正则表达式匹配限制为仅单词匹配。
更新:
正如其他答案中所建议的,left_semi
join 可能会更好地工作,以避免在有多个匹配项时出现重复的行。默认的inner
连接适用于df2
的列要包含在结果数据集中的情况。
【讨论】:
【参考方案2】:您可以根据df1文本包含df2文本中的字符串的条件进行左半连接,并且单词前后有一个空格:
val result = df1.as("df1").join(
df2.as("df2"),
expr("df1.text rlike concat(' ', df2.text, ' ')"),
"left_semi"
)
result.show(false)
+---+-----+-----------------------+
|ID |Name |Text |
+---+-----+-----------------------+
|1 |Test1|Amount paid to User1 dt|
|2 |Test2|Amount paid to User1 dt|
+---+-----+-----------------------+
【讨论】:
【参考方案3】:您可以将 df1 中的 Text
列拆分为单词数组,然后使用 array_contains
函数进行连接:
val df3 = df1.alias("df1")
.join(
df2.alias("df2"),
array_contains(split(col("df1.Text"), "\\s"), col("df2.Text")),
"left_semi"
)
df3.show(false)
//+---+-----+-----------------------+
//|ID |Name |Text |
//+---+-----+-----------------------+
//|1 |Test1|Amount paid to User1 dt|
//|2 |Test2|Amount paid to User1 dt|
//+---+-----+-----------------------+
【讨论】:
如果要匹配的字符串有空格(例如“支付给”),split
可能不起作用。
@LeoC 同意。并且可能也不是最好的解决方案,但希望至少为单个单词关键字展示另一种方法:)以上是关于字符串列包含通过 spark scala 精确匹配的单词的主要内容,如果未能解决你的问题,请参考以下文章