Вот что я могу сделать, используя SparkSQL 2.4.0 + встроенная функция filter :
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()))