首页 > 解决方案 > 在 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 和列表理解做我想做的事,但我希望以最优化的方式做到这一点,因为实际数据有数亿行

标签: pythonregexdataframeapache-sparkpyspark

解决方案


您可以使用

regex_replace(col("name"), "(?=(.{3})).", r"$1 ")

请参阅正则表达式演示。细节:

  • (?=(.{3}))- 一个积极的前瞻,它捕获(到第 1 组中$1)三个字符,而不是立即位于当前位置右侧的换行符
  • .- 除换行符之外的任何字符,已消耗(它将被删除,并被从该字符开始的 3 个字符条纹替换)。

推荐阅读