为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Array 上使用

如何在 Array 上使用

翻阅古今 2022-06-22 15:49:54
我有一个 pyspark 数据框,它包含 4 列。我想从一列中提取一些字符串,它的类型是Array of strings. 我使用regexp_extract了函数,但它返回了一个错误,因为regexp_extract它只接受一个字符串。示例数据框:id |  last_name | age | Identificator------------------------------------------------------------------12 | AA         | 23  |  "[""AZE","POI","76759","T86420","ADAPT"]"------------------------------------------------------------------24 | BB         | 24  | "[""SDN","34","35","AZE","21054","20126"]"------------------------------------------------------------------我想提取所有数字:- contain 4, 5 or 6 digits - it should not attached to a letters. - if attached to letter Z ok, I should extract it. - save it in a new column in my Dataframe.我开始这样做,但它不起作用,因为标题是一个字符串数组。expression = r'([0-9]){4,6}' df = df.withColumn("extract", F.regexp_extract(F.col("Identificator"), expression, 1))如何使用 regexp_extract 或其他解决方案提取这些数字?谢谢
查看完整描述

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()))



查看完整回答
反对 回复 2022-06-22
  • 1 回答
  • 0 关注
  • 113 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信