Regex Spark-从具有不同列类型的数据帧行中删除特殊字符

Regex Spark-从具有不同列类型的数据帧行中删除特殊字符,regex,scala,apache-spark,dataframe,rdd,Regex,Scala,Apache Spark,Dataframe,Rdd,假设我有一个包含许多列的数据框架,有些是string类型,有些是int类型,有些是map类型 e、 g。 字段/列类型:stringType | intType | mapType | 我想从字符串和映射类型的所有列中删除一些字符,如“\ux”和 因此,Dataframe/RDD的结果将是: |------------------------------------------------------------------------ |myString1 |myInt1| m

假设我有一个包含许多列的数据框架,有些是string类型,有些是int类型,有些是map类型

e、 g。 字段/列类型:stringType | intType | mapType |

我想从字符串和映射类型的所有列中删除一些字符,如“\ux”和 因此,Dataframe/RDD的结果将是:

|------------------------------------------------------------------------
|myString1     |myInt1|     myMap1|...                                 |
|------------------------------------------------------------------------
|"thisisstring"| 123 |{"str11inmap":1,"str21inmap":2, "str31inmap": 31}|...
|"thisisstring"| 456 |{"str12inmap":1,"str22inmap":2, "str32inmap": 32}|...
|"thisisstring"| 789 |{"str13inmap":1,"str23inmap":2, "str33inmap": 33}|...
|-------------------------------------------------------------------------
我不确定是否最好将数据帧转换为RDD并使用它或在数据帧中执行工作

另外,我不知道如何以我使用scala的最佳方式处理不同列类型的regexp。 我希望对这两种类型的所有列执行此操作,即string和map,尽量避免使用以下列名:

def cleanRows(mytabledata: DataFrame): RDD[String] = {

//this will do the work for a specific column (myString1) of type string
val oneColumn_clean = mytabledata.withColumn("myString1", regexp_replace(col("myString1"),"[_#]",""))

       ...
//return type can be RDD or Dataframe...
}
有什么简单的解决方案可以实现这一点吗?
谢谢

一个选项是定义两个UDF来分别处理字符串类型列和映射类型列:

import org.apache.spark.sql.functions.udf
val df = Seq(("this_is#string", 3, Map("str1_in#map" -> 3))).toDF("myString", "myInt", "myMap")
df.show
+--------------+-----+--------------------+
|      myString|myInt|               myMap|
+--------------+-----+--------------------+
|this_is#string|    3|Map(str1_in#map -...|
+--------------+-----+--------------------+
1个用于处理字符串类型列的Udf:

def remove_string: String => String = _.replaceAll("[_#]", "")
def remove_string_udf = udf(remove_string)
def remove_map: Map[String, Int] => Map[String, Int] = _.map{ case (k, v) => k.replaceAll("[_#]", "") -> v }
def remove_map_udf = udf(remove_map)
2个用于处理映射类型列的Udf:

def remove_string: String => String = _.replaceAll("[_#]", "")
def remove_string_udf = udf(remove_string)
def remove_map: Map[String, Int] => Map[String, Int] = _.map{ case (k, v) => k.replaceAll("[_#]", "") -> v }
def remove_map_udf = udf(remove_map)
3将UDF应用于相应的列以进行清理:

df.withColumn("myString", remove_string_udf($"myString")).
   withColumn("myMap", remove_map_udf($"myMap")).show

+------------+-----+-------------------+
|    myString|myInt|              myMap|
+------------+-----+-------------------+
|thisisstring|    3|Map(str1inmap -> 3)|
+------------+-----+-------------------+

一个选项是定义两个UDF来分别处理字符串类型列和映射类型列:

import org.apache.spark.sql.functions.udf
val df = Seq(("this_is#string", 3, Map("str1_in#map" -> 3))).toDF("myString", "myInt", "myMap")
df.show
+--------------+-----+--------------------+
|      myString|myInt|               myMap|
+--------------+-----+--------------------+
|this_is#string|    3|Map(str1_in#map -...|
+--------------+-----+--------------------+
1个用于处理字符串类型列的Udf:

def remove_string: String => String = _.replaceAll("[_#]", "")
def remove_string_udf = udf(remove_string)
def remove_map: Map[String, Int] => Map[String, Int] = _.map{ case (k, v) => k.replaceAll("[_#]", "") -> v }
def remove_map_udf = udf(remove_map)
2个用于处理映射类型列的Udf:

def remove_string: String => String = _.replaceAll("[_#]", "")
def remove_string_udf = udf(remove_string)
def remove_map: Map[String, Int] => Map[String, Int] = _.map{ case (k, v) => k.replaceAll("[_#]", "") -> v }
def remove_map_udf = udf(remove_map)
3将UDF应用于相应的列以进行清理:

df.withColumn("myString", remove_string_udf($"myString")).
   withColumn("myMap", remove_map_udf($"myMap")).show

+------------+-----+-------------------+
|    myString|myInt|              myMap|
+------------+-----+-------------------+
|thisisstring|    3|Map(str1inmap -> 3)|
+------------+-----+-------------------+

嗨@Psidom,谢谢你的提示。这似乎很好,但是这样,需要映射Dataframe中的所有列。我在寻找更通用的用法。也许不是那么直截了当。。无论如何,投票吧,txHi@Psidom,通过任何改变,有没有办法创建def remove_map的模板函数:。。类似于:def remove_map[T]:map[String,T]=>map[String,T]=我尝试了几种方法,但其中任何一种都有效。这将避免使用多个函数,每个MapI组合使用一个。我不确定这是否可行。也许值得单独问一个问题,看看你是否能得出任何信息丰富的答案。谢谢,我问了,但没有回答。。嗨@Psidom,谢谢你的提示。这似乎很好,但是这样,需要映射Dataframe中的所有列。我在寻找更通用的用法。也许不是那么直截了当。。无论如何,投票吧,txHi@Psidom,通过任何改变,有没有办法创建def remove_map的模板函数:。。类似于:def remove_map[T]:map[String,T]=>map[String,T]=我尝试了几种方法,但其中任何一种都有效。这将避免使用多个函数,每个MapI组合使用一个。我不确定这是否可行。也许值得单独问一个问题,看看你是否能得出任何信息丰富的答案。谢谢,我问了,但没有回答。。