用其他列值pyspark替换包含美元符号($)的子字符串[重复]

Posted

技术标签:

【中文标题】用其他列值pyspark替换包含美元符号($)的子字符串[重复]【英文标题】:Replace substring containing dollar sign ($) with other column value pyspark [duplicate] 【发布时间】:2019-03-18 11:15:02 【问题描述】:

我正在尝试将子字符串 '$NUMBER' 替换为每行的“数字”列中的值。 我试过了

from pyspark.sql.functions import udf
from pyspark.sql.Types import StringType

replace_udf = udf(
    lambda long_text, number: long_text.replace("$NUMBER", number),
    StringType()
)

df = df.withColumn('long_text',replace_udf(col('long_text'),col('number')))

from pyspark.sql.functions import expr

df = df.withColumn('long_text',expr("regexp_replace(long_text, '$NUMBER', number)"))

但没有任何效果。我无法弄清楚另一列如何替代子字符串。

示例:

df1 = spark.createDataFrame(
    [
        ("hahaha the $NUMBER is good",3),
        ("i dont know about $NUMBER",2),
        ("what is $NUMBER doing?",5),\
        ("ajajaj $NUMBER",2),
        ("$NUMBER dwarfs",1)
    ],
    ["long_text","number"]
) 

输入:

+---------------------------------+------+
|           long_text .           |number|
+---------------------------------+------+
|hahaha the $NUMBER is good       |     3|
|    what is $NUMBER doing?       |     5|
|          ajajaj $NUMBER         |     2|
+---------------------------------+------+

预期输出:

+--------------------+------+
|           long_text|number|
+--------------------+------+
|hahaha the 3 is good|     3|
|    what is 5 doing?|     5|
|          ajajaj 123|     2|
+--------------------+------+

答案未涵盖列替换的类似问题: Spark column string replace when present in other column (row)

【问题讨论】:

你能提供一个示例输入和预期输出吗? $ 是正则表达式中的一个特殊符号,表示在字符串末尾匹配。您需要用斜线对其进行转义:\$NUMBER 【参考方案1】:

问题是$在正则表达式中有特殊含义,表示匹配行尾。所以你的代码:

regexp_replace(long_text, '$NUMBER', number)

正在尝试匹配模式:行尾后跟文字字符串NUMBER(它永远无法匹配任何内容)。

为了匹配$(或任何其他正则表达式特殊字符),您必须使用\ 对其进行转义。

from pyspark.sql.functions import expr

df = df.withColumn('long_text',expr("regexp_replace(long_text, '\$NUMBER', number)"))
df.show()
#+--------------------+------+
#|           long_text|number|
#+--------------------+------+
#|hahaha the 3 is good|     3|
#|    what is 5 doing?|     5|
#|            ajajaj 2|     2|
#+--------------------+------+

【讨论】:

我认为您需要转义反斜杠或将其设为原始字符串。【参考方案2】:

您必须先使用 str() 将数字列转换为字符串,然后才能在 lambda 中使用 with replace:

from pyspark.sql import types as T
from pyspark.sql import functions as F

l = [(  'hahaha the $NUMBER is good',    3)
     ,('what is $NUMBER doing?'         ,   5)
     ,('ajajaj $NUMBER  '       ,  2)]
df = spark.createDataFrame(l,['long_text','number'])

#Just added str() to your function
replace_udf = F.udf(lambda long_text, number: long_text.replace("$NUMBER", str(number)), T.StringType())

df.withColumn('long_text',replace_udf(F.col('long_text'),F.col('number'))).show()

+--------------------+------+ 
|           long_text|number| 
+--------------------+------+ 
|hahaha the 3 is good|     3| 
|    what is 5 doing?|     5|
|           ajajaj 2 |     2| 
+--------------------+------+

【讨论】:

以上是关于用其他列值pyspark替换包含美元符号($)的子字符串[重复]的主要内容,如果未能解决你的问题,请参考以下文章

当列表值与Pyspark数据帧中的列值的子字符串匹配时,填充新列

根据熊猫中的另一个列值有条件地填充列值

如何用同一数据框中其他列的实际列值替换一列中的字符串值?

替换字符串中的反向引用语法(为啥是美元符号?)

PySpark DataFrame:标记某些列值更改的行

Pyspark根据其他列值添加新列