pyspark - 如何检查一个短语是否是英文的
问题描述
我需要在 PySpark-Sql 中使用语言属性丰富我的数据框,该属性基本上告诉每一行论文标题的语言。我只需要过滤掉英文论文。我有几千万篇论文,所以我需要并行进行。
在集群上安装库之后,我使用名为langdetect
( https://pypi.org/project/langdetect/ ) 的 Python 库注册了一个 UDF。我正在使用以下代码:
from langdetect import detect
def lang_detector(_s):
try:
lan = detect(_s)
except:
lan = 'null'
return lan
detect2 = udf(lang_detector, StringType())
papers_abs_fos_en = papers_abs \
.join(papersFos_L1, "PaperId") \
.withColumn("Lang", detect2(col("PaperTitle"))) \
.filter("Lang =='en'") \
.select("PaperId", "Rank", "PaperTitle", "RefCount", "CitCount", "FoSList")
它有效,但即使在 ca 10M 标题上也需要很长时间。我不确定这是由于langdetect
UDF 还是我做错了什么,但我将不胜感激任何建议!
非常感谢!保罗
解决方案
感谢 cronoik 确认这一点。我最终得到了一个不同的解决方案,该解决方案需要 6 分钟以上才能处理 9,500 万份文档。基本上,我在 NLTK 中制作了一组 Brown 数据集中的所有单词,并将其作为广播变量分发给节点。然后我为数据框中的每个文档计算了该集合中出现的单词的比例。如果它> 75%,那么我试探性地得出结论它一定是英语。这是嵌入到 UDF 中的代码。
from nltk.corpus import brown
import re
bwn = set([x.lower() for x in brown.words()])
bc_brown = sc.broadcast(bwn)
def is_en(_s):
tok = set(re.findall(r"\w+", _s.lower()))
return len(tok & bc_brown.value) / len(tok)
isEn = udf(is_en)
papers_abs_fos_en = papers_abs \
.join(papersFos_L1, "PaperId") \
.filter(isEn(col("PaperTitle")) > 0.75) \
.select("PaperId", "Rank", "PaperTitle", "RefCount", "CitCount", "FoSList")
推荐阅读
- dart - RenderRepaintBoundary 到图像而不将小部件添加到屏幕
- python - main() 中的 sys.argv 但在前一个函数中引用了全局变量
- javascript - 循环遍历 DIV 元素并获取动态添加的文本输入 - PHP
- ruby-on-rails - 带有 Rails 的 webpack-dev-server 返回 400 错误
- regex - 正则表达式匹配特定字符串 + 可选空格 + 8 位数字
- android - 尝试在空对象引用上调用虚拟方法“void android.widget.AdapterView.setEmptyView(android.view.View)”
- javascript - JavaScript 仅在满足特定条件时才为变量赋值(不重复)
- mongodb - mongodb 是构建与健康相关的 Web 应用程序的正确选择吗?
- javascript - 使用 vuetify 完美对齐表格
- java - 解决错误 java.io.StreamCorruptedException: Inconsistent vector internals