Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.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
Python Pypark正则表达式联接_Python_Regex_Apache Spark_Pyspark - Fatal编程技术网

Python Pypark正则表达式联接

Python Pypark正则表达式联接,python,regex,apache-spark,pyspark,Python,Regex,Apache Spark,Pyspark,我有一个Pyspark数据帧,它需要与另一个基于字符串列的数据帧连接。例如 (bob1,“a.b.*c”)(bob2,“a.b.c”) 加入 (tom1,“a.b.d.c”)(tom2,“a.b.c”) 在第二列(模式)上,应该给出:(bob1,tom1)(bob2,tom2)。我知道这可以使用rlike来完成,但为此,我需要将模式列转换为实际的正则表达式。所以 a.b.*.c变成^a.b.(\w+).c$ a.b.c变成^a.b.c$ 我做这个转换有困难。我尝试使用regex_replac

我有一个Pyspark数据帧,它需要与另一个基于字符串列的数据帧连接。例如

(bob1,“a.b.*c”)(bob2,“a.b.c”)

加入

(tom1,“a.b.d.c”)(tom2,“a.b.c”)

在第二列(模式)上,应该给出:(bob1,tom1)(bob2,tom2)。我知道这可以使用rlike来完成,但为此,我需要将模式列转换为实际的正则表达式。所以

  • a.b.*.c变成^a.b.(\w+).c$
  • a.b.c变成^a.b.c$

我做这个转换有困难。我尝试使用regex_replace(),但由于输出中有\项,它插入\项两次而不是一次。

regexp_replace
可以使用:

df1=spark.createDataFrame([
(“bob1”、“a.b.*d”)、(“bob2”、“a.b.c”)、[“col1”、“col2”])
df2=spark.createDataFrame([
(“tom1”、“a.b.c.d”)、(“tom2”、“a.b.c”)、[“col3”、“col4”])
df1=df1.带列(“连接列”、F.concat(F.lit(“^”)、F.regexp\u替换(F.col(“col2”)、“\\*”、“(\\\\w+)”、F.lit(“$”)
df_join=df1.join(df2,F.expr(“col4 rlike join_col”))
df_加入。show()
印刷品

+----+-------+-------------+----+-------+
|col1 | col2 | join | u col | col3 | col4|
+----+-------+-------------+----+-------+
|bob1 | a.b.*.d | ^a.b.(\w+).d$| tom1 | a.b.c.d|
|bob2 | a.b.c | ^a.b.c$| tom2 | a.b.c|
+----+-------+-------------+----+-------+
\w+
周围的括号可以省略

不幸的是,
df_joined.explain()
表明
rlike
连接会导致卡特尔产品:

==物理计划==
卡特尔产品col4#5 RLIKE join#col#26
:-*(1)项目[col1#0,col2#1,concat(^,regexp#u替换(col2#1,\*,(\\w+),$)作为联接列26]
:+-*(1)过滤器不为空(concat(^,regexp\u replace(col2\35; 1,\*,(\\w+),$))
:+-*(1)扫描现有RDD[col1#0,col2#1]
+-*(2)过滤器不为空(col4#5)
+-*(2)扫描现有RDD[col3#4,col4#5]

Ahh,谢谢!CartesianProduct在这里是可以预期的,但是在我的例子中,连接的一侧与另一侧相比确实很小,所以我没有那么担心。所以,
broacasting
较小的df,在这里可能会有帮助。我意识到两个数据帧都相对较小。一个约为1gb,另一个约为100mb。我刚刚收集了数据帧,并用纯python代码替换了所有逻辑,它运行得非常快。完成这项工作大约需要10秒钟。我想我甚至不需要使用spark来读取文件,我只需要使用python代码在驱动程序中读取它。使用pandas,它甚至可以更快@Dexter:)事实上,这是一个有趣的场景。我想,
*
可能不仅出现在第三位,而且无处不在,对吗?没错。那么我认为除了笛卡尔积之外,没有别的方法了。除非数据集相对较小。然后您可以从df1中找到模式并提取它们(
df1.collect
)。通过将
\w
替换为
*
将模式应用于df2,最后使用内部联接将其联接。但这有一个缺点,那就是你增加了复杂性和额外的动作。这很聪明!我刚刚检查了生产数据,实际上所有的通配符都只出现在第二位。我可以用你的方法!