我正在尝试从字符串“ 60 ML扑热息痛和0.5 ML XYZ”中提取60 ML和0.5 ML。此字符串是spark数据帧中列X的一部分。尽管我可以测试我的正则表达式代码以在正则表达式验证器中提取60 ML和0.5 ML,但我无法使用regexp_extract来提取它,因为它仅针对第一个匹配项。因此,我只得到60毫升。
您能建议我使用UDF的最佳方法吗?
答案 0 :(得分:0)
以下是使用python UDF的方法:
from pyspark.sql.types import *
from pyspark.sql.functions import *
import re
data = [('60 ML of paracetomol and 0.5 ML of XYZ',)]
df = sc.parallelize(data).toDF('str:string')
# Define the function you want to return
def extract(s)
all_matches = re.findall(r'\d+(?:.\d+)? ML', s)
return all_matches
# Create the UDF, note that you need to declare the return schema matching the returned type
extract_udf = udf(extract, ArrayType(StringType()))
# Apply it
df2 = df.withColumn('extracted', extract_udf('str'))
Python UDF比本机DataFrame操作具有明显的性能下降。再多考虑一下之后,这是另一种无需使用UDF的方法。一般的想法是用逗号替换所有不需要的文本,然后以逗号分割以创建最终值数组。如果只需要数字,则可以更新正则表达式以将“ ML”从捕获组中删除。
pattern = r'\d+(?:\.\d+)? ML'
split_pattern = r'.*?({pattern})'.format(pattern=pattern)
end_pattern = r'(.*{pattern}).*?$'.format(pattern=pattern)
df2 = df.withColumn('a', regexp_replace('str', split_pattern, '$1,'))
df3 = df2.withColumn('a', regexp_replace('a', end_pattern, '$1'))
df4 = df3.withColumn('a', split('a', r','))