python - 在 PySpark 中使用正则表达式创建 N-Gram
问题描述
我有一个带有名称的 pyspark 数据框列:
| name |
--------------
|Lebron James|
|Kyrie Irving|
|Kevin Durant|
我想创建一个新列,如下所示:
| name | trigram |
-----------------------------------------
|Lebron James| Leb ebr bro on Jam ame es
|Kyrie Irving| ...
|Kevin Durant| ...
到目前为止我有
df.withColumn("trigram", regex_replace(col("name"), "([A-Za-z0-9\s]{3})(?!$)", r"$1 "))
但这输出:
| name | trigram |
--------------------------------------
|Lebron James| Leb ron Ja mes
|Kyrie Irving| Kyr ie Irv ing
|Kevin Durant| Kev in Dur ant
注意:不使用 udfs 很重要。我可以简单地用 udf 和列表理解做我想做的事,但我希望以最优化的方式做到这一点,因为实际数据有数亿行
解决方案
您可以使用
regex_replace(col("name"), "(?=(.{3})).", r"$1 ")
请参阅正则表达式演示。细节:
(?=(.{3}))
- 一个积极的前瞻,它捕获(到第 1 组中$1
)三个字符,而不是立即位于当前位置右侧的换行符.
- 除换行符之外的任何字符,已消耗(它将被删除,并被从该字符开始的 3 个字符条纹替换)。