apache-spark - Spark Join 最佳匹配效率问题
问题描述
我有 2 个数据框:
df_1
大约有 5 亿条记录和约 100 列df_2
约 5000 万条记录和 4 列
我需要在其中两列df_1
上df_2
完全匹配并在第三列上保持最佳匹配。最佳匹配是指从左到右存在一个:多的关系,但是我只想在长度方面在右侧接收最佳匹配。
例如
# df_1
col1 col2 col3
---------------------------
a b abcde
# df_2
col1 col2 col3 col4
-------------------------------
a b a 90
a b ab 100
a b abc 150
a c abc 90
col1
因此,当我匹配并且col2
完全匹配并且col3
包含字符串的最佳匹配时,连接的期望结果是:
col1 col2 col3 col4
-------------------------------
a b abcde 150
这里有一些对我不利的观点:
- 左侧的长度
col3
一般在 10 到 15 个字符之间,右侧的长度可以从 1 个字符到 9 个字符不等 - 两者
df_1
和df_2
都同样偏斜col3
虽然我已经完成了这项工作,但我的表现却很糟糕。
我已经尝试了以下解决方案,但仍然没有得到任何地方:
- 广播
df_2
(因为太大而无法广播) - 完全加入
col1
并col1
使用like
(col3
糟糕) - 爆出 in 的值
col3
以df_2
尝试消除偏差(改进但仍然缓慢) - 持久化数据并循环遍历右侧的每个长度,并准确连接
col1
,col2
和col3
(左侧的连接是 的子字符串col3
)(改进但仍然很慢)
使用 spark 进行此连接的最高效方法是什么?
解决方案
更好的选择是在加入之前减少数据大小(我们不能根除加入)。我们可以减少如下:
一、加载数据
scala> import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.expressions.Window
scala> import org.apache.spark.sql.functions._
import org.apache.spark.sql.functions._
scala> df1.show
+---+---+-----+
| c1| c2| c3|
+---+---+-----+
| a| b|abcde|
| c| d| fd|
+---+---+-----+
scala> df2.show
+---+---+----+---+
| c1| c2| c3| c4|
+---+---+----+---+
| a| b| a| 90|
| a| b| abd|100|
| a| b|abcd|150|
| c| d|wewe| 79|
+---+---+----+---+
现在我们需要在加入之前减少 df2 的大小(这将减少加入的时间,因为数据大小比较少)使用窗口函数并找出两列的最大值
scala> df2.withColumn("len", length($"c3")).withColumn("res", row_number().over(wind1)).filter($"res" === 1).withColumn("res2", row_number().over(wind2)).filter($"res2"=== 1).select("c1", "c2", "c3", "c4").show()
+---+---+----+---+
| c1| c2| c3| c4|
+---+---+----+---+
| c| d|wewe| 79|
| a| b|abcd|150|
+---+---+----+---+
要尝试的事情:
1>您可以加入这个减少的数据框并应用您正在使用的逻辑
2>尝试做联合df1.withColumn("c4", lit(0)).union(df2)
,然后应用上述逻辑。
希望这可以帮助
推荐阅读
- python-3.x - 在卷积神经网络模型中找不到文件
- 2sxc - 条目仅对用户和特定角色可见
- c# - 使用 FileHelpers 时,如何在 SQL Server 中将 CSV 空字符串加载为 NULL?
- css - CSS行尾选择器添加装饰
- java - KeyListener 应该工作,然后退出程序,但它没有(AutoClicker)
- python - 无法在 Mac OSC High Sierra 上安装 Python GDAL
- android - 无法在 android 中使用 AWS 创建组
- php - 在控制器上处理时有没有办法获取数据 - Laravel PHP
- php - 在 Plesk REST API 中创建邮件帐户
- ssh - 由于您的组,如何确定您是否可以使用 SFTP 写入目录?