1 回答
TA贡献1895条经验 获得超3个赞
以下是我可以使用 SparkSQL 2.4.0+内置函数过滤器执行的操作:
from pyspark.sql.functions import expr
df.withColumn('text_new', expr('filter(text, x -> x rlike "^Z?[0-9]{4,6}$")')) \
.show(truncate=False)
#+-----------------------------------+---------------------+
#|text |text_new |
#+-----------------------------------+---------------------+
#|[AZE, POI, 76759, T86420, ADAPT] |[76759] |
#|[SDN, 34, Z8735, AZE, 21054, 20126]|[Z8735, 21054, 20126]|
#+-----------------------------------+---------------------+
结果是一个包含匹配项的数组。正则表达式^Z?[0-9]{4,6}$匹配 4-6 位可选地前面有字符“Z”的数字。
编辑:对于旧版本的 Apache Spark,使用udf():
import re
from pyspark.sql.functions import udf
from pyspark.sql.types import ArrayType, StringType
# regex pattern:
ptn = re.compile('^Z?[0-9]{4,6}$')
# create an udf to filter array
array_filter = udf(lambda arr: [ x for x in arr if re.match(ptn, x) ] if type(arr) is list else arr, ArrayType(StringType()))
df.withColumn('text_new', array_filter('text')) \
.show(truncate=False)
Edit-2:根据您的评论,从 'Z' 到 'MOD' 并删除前导MOD,使用 lstrip() 删除此子字符串。调整以下:
ptn = re.complie(r'^(?:MOD)?[0-9]{4,6}$')
array_filter = udf(lambda arr: [ x.lstrip('MOD') for x in arr if re.match(ptn, x) ] if type(arr) is list else arr, ArrayType(StringType()))
添加回答
举报