Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark Spark Join最佳匹配效率问题_Apache Spark_Join_Pyspark - Fatal编程技术网

Apache spark Spark Join最佳匹配效率问题

Apache spark Spark Join最佳匹配效率问题,apache-spark,join,pyspark,Apache Spark,Join,Pyspark,我有两个数据帧: df_1拥有约5亿条记录和约100列 df_2有约5000万条记录和4列 我需要将df_1与df_2左连接,其中两列精确匹配,第三列最佳匹配。所谓最佳匹配,我的意思是有一个:从左到右的关系很多,但我只想在长度上得到右侧的最佳匹配 e、 g 因此,当我精确地匹配col1和col2以及col3所包含字符串的最佳匹配时,联接的预期结果是: col1 col2 col3 col4 ------------------------------- a b

我有两个数据帧:

  • df_1
    拥有约5亿条记录和约100列
  • df_2
    有约5000万条记录和4列
我需要将
df_1
df_2
左连接,其中两列精确匹配,第三列最佳匹配。所谓最佳匹配,我的意思是有一个:从左到右的关系很多,但我只想在长度上得到右侧的最佳匹配

e、 g

因此,当我精确地匹配
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
    上精确连接,并在
    col3
    上使用
    类似的
    (糟糕)
  • df_2
    中的
    col3
    上的值分解出来,尝试与歪斜作斗争(改善但仍然缓慢)
  • 保留数据并循环右侧的每个长度,并在
    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> 尝试使用列(“c4”,lit(0)).union(df2)
执行union
df1,然后应用上述逻辑


希望这有帮助

,在df1中,你需要一个更大的字符串&从df2中,你需要最大的数字,或者从两个数据帧中,你需要一个更大的串联和更大的数字??因此在df1中,我在col3中有一个字符串,我需要在d2 col3中找到最长的匹配,以带回COL4。请你解释一下,本质上,df1是我模型的主要输出,df2是一个查找表,使我能够通过连接其他3列返回
col4
,以便以后使用。第3列具有可变长度(每行一个),我需要返回对应的col4,以匹配COL3中最长的值。您是否根据col_4值选择第三行,因为它在其他a和b组合(150)中最高?
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|
+---+---+----+---+
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|
+---+---+----+---+