如何将 Pyspark 中由某些字符分隔的每个单词大写?
How can I capitalize each word delimited by some characters in Pyspark?
我目前正在使用 Pyspark,我遇到了一个看似简单的问题。
我想将每个单词的首字母大写,即使这些单词被以下列表中的字符分隔:
delimiter_list = [' ', '(', '+', '/', '-']
实际上,initcap
仅适用于由空格类型分隔的单词。
有没有有效的解决方案?
以下是一些输入输出示例:
input
output
baden-baden
Baden-Baden
markranstadt/brandenburg-kirchmöser
Markranstadt/Brandenburg-Kirchmöser
ostrow mazowiecki/bialystok
Ostrow Mazowiecki/Bialystok
我认为可能需要 UDF。由于需要转义某些特殊字符,例如 (
和 +
.
,您可能需要手动管理正则表达式模式
import pyspark.sql.functions as F
import re
df.show(truncate=False)
+-----------------------------------+
|words |
+-----------------------------------+
|baden-baden |
|markranstadt/brandenburg-kirchmöser|
|ostrow mazowiecki/bialystok |
+-----------------------------------+
words_udf = F.udf(
lambda w: re.sub(r'(^| |\(|\+|-|/)([a-z])', lambda x: x.group(1) + x.group(2).upper(), w)
)
df.select(words_udf('words').alias('words')).show(truncate=False)
+-----------------------------------+
|words |
+-----------------------------------+
|Baden-Baden |
|Markranstadt/Brandenburg-Kirchmöser|
|Ostrow Mazowiecki/Bialystok |
+-----------------------------------+
由于分隔符不同,您可以先添加一个通用分隔符,例如 #
在列表 delimiter_list
中的每个字符之后使用 regexp_replace
:
regexp_replace(words, '(\s|\(|\+|-|\/)(.)', '#')
现在,您可以按 #
拆分并使用 transform
函数通过将每个元素大写来转换结果数组。最后,使用array_join
函数加入数组元素得到原始字符串:
from pyspark.sql import functions as F
df1 = df.withColumn(
"words_capitalized",
F.expr(r"""
array_join(
transform(
split(regexp_replace(words, '(\s|\(|\+|-|\/)(.)', '#'), '#'),
x -> initcap(x)
),
""
)
""")
)
df1.show(truncate=False)
#+-----------------------------------+-----------------------------------+
#|words |words_capitalized |
#+-----------------------------------+-----------------------------------+
#|baden-baden |Baden-Baden |
#|markranstadt/brandenburg-kirchmöser|Markranstadt/Brandenburg-Kirchmöser|
#|ostrow mazowiecki/bialystok |Ostrow Mazowiecki/Bialystok |
#+-----------------------------------+-----------------------------------+
我目前正在使用 Pyspark,我遇到了一个看似简单的问题。
我想将每个单词的首字母大写,即使这些单词被以下列表中的字符分隔:
delimiter_list = [' ', '(', '+', '/', '-']
实际上,initcap
仅适用于由空格类型分隔的单词。
有没有有效的解决方案? 以下是一些输入输出示例:
input | output |
---|---|
baden-baden | Baden-Baden |
markranstadt/brandenburg-kirchmöser | Markranstadt/Brandenburg-Kirchmöser |
ostrow mazowiecki/bialystok | Ostrow Mazowiecki/Bialystok |
我认为可能需要 UDF。由于需要转义某些特殊字符,例如 (
和 +
.
import pyspark.sql.functions as F
import re
df.show(truncate=False)
+-----------------------------------+
|words |
+-----------------------------------+
|baden-baden |
|markranstadt/brandenburg-kirchmöser|
|ostrow mazowiecki/bialystok |
+-----------------------------------+
words_udf = F.udf(
lambda w: re.sub(r'(^| |\(|\+|-|/)([a-z])', lambda x: x.group(1) + x.group(2).upper(), w)
)
df.select(words_udf('words').alias('words')).show(truncate=False)
+-----------------------------------+
|words |
+-----------------------------------+
|Baden-Baden |
|Markranstadt/Brandenburg-Kirchmöser|
|Ostrow Mazowiecki/Bialystok |
+-----------------------------------+
由于分隔符不同,您可以先添加一个通用分隔符,例如 #
在列表 delimiter_list
中的每个字符之后使用 regexp_replace
:
regexp_replace(words, '(\s|\(|\+|-|\/)(.)', '#')
现在,您可以按 #
拆分并使用 transform
函数通过将每个元素大写来转换结果数组。最后,使用array_join
函数加入数组元素得到原始字符串:
from pyspark.sql import functions as F
df1 = df.withColumn(
"words_capitalized",
F.expr(r"""
array_join(
transform(
split(regexp_replace(words, '(\s|\(|\+|-|\/)(.)', '#'), '#'),
x -> initcap(x)
),
""
)
""")
)
df1.show(truncate=False)
#+-----------------------------------+-----------------------------------+
#|words |words_capitalized |
#+-----------------------------------+-----------------------------------+
#|baden-baden |Baden-Baden |
#|markranstadt/brandenburg-kirchmöser|Markranstadt/Brandenburg-Kirchmöser|
#|ostrow mazowiecki/bialystok |Ostrow Mazowiecki/Bialystok |
#+-----------------------------------+-----------------------------------+