python - 如何在pySpark中从字符串数据框中有效替换多个正则表达式模式的所有实例?

标签 python apache-spark hadoop pyspark

我在Hadoop中有一个表,其中包含70亿个字符串,这些字符串本身可以包含任何内容。我需要从包含字符串的列中删除每个名称。一个示例字符串将是“约翰去公园”,我需要从中删除“约翰”,理想情况下只需替换为“[名称]”。

在“约翰和玛丽进入市场”的情况下,输出为“[NAME],[NAME]进入市场”。

为此,我列出了最常见的20k名称。

我可以访问Hue(Hive,Impala)和Zeppelin(Spark,Python和库)来执行此操作。

我已经在数据库中进行了尝试,但是由于无法更新列或遍历变量而使其无法使用,因此使用Python和PySpark似乎是最好的选择,尤其是考虑到计算数量(20k名称* 70亿输入)字符串)

#nameList contains ['John','Emma',etc]
def removeNames(line, nameList):
    str_line= line[0]
    for name in nameList:
        rx = f"(^| |[[:^alpha:]])({name})( |$|[[:^alpha:]])"
        str_line = re.sub(rx,'[NAME]', str_line)
    str_line= [str_line]
    return tuple(str_line)

df = session.sql("select free_text from table")
rdd = df.rdd.map(lambda line: removeNames(line, nameList))
rdd.toDF().show()


代码正在执行,但是即使我将输入文本限制为1000行(这对于Spark来说也不是),这也要花一个半小时,并且最终输出中实际上并未替换这些行。

我想知道的是:为什么 map 实际上不更新RDD的行,我如何使它更有效,使其在合理的时间内执行?

这是我的第一次发布,因此,如果缺少必要的信息,我将尽力填写。

谢谢!

最佳答案

如果您仍然对此感到好奇,通过使用udf(您的removeNames函数),Spark会将所有数据序列化到主节点,从根本上击败了您使用Spark进行分布式操作。正如注释中建议的方法一样,如果您使用regexp_replace()方法,Spark将能够将所有数据保留在分布式节点上,从而使所有数据保持分布式并提高性能。

关于python - 如何在pySpark中从字符串数据框中有效替换多个正则表达式模式的所有实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56368211/

相关文章:

python - Django 可重用应用程序,具有与friendfeed 类似的功能

python - 保存的数据带有不需要的引号

scala - Spark SQL为Hive构建吗?

hadoop - 有没有一种方法可以给Hive中的表提供 “second name”,以便用户可以引用表的任何一个名称并检索相同的内容?

hadoop - Spark 数据集写入 HDFS 期间创建的空分区

python - 如何一次遍历两个字典?

python - 切片 python 列表

python - 无论我做什么都无法使用 Selenium 选择元素

java - Karlhigley LSH ANN 模型,用于查找给出空结果的最近邻居

Scala:未指定的值参数证据$3