2017-03-16 11 views
1

私は多くの列を持つデータフレームをしたと仮定すると、行DATAFRAMEから特殊文字を削除し、いくつかのタイプ文字列他の人がint型を入力し、他の人がマップを入力します。スパーク - 異なる列タイプ

フィールド/列types: stringType|intType|mapType<string,int>|...

|-------------------------------------------------------------------------- 
| myString1  |myInt1| myMap1            |... 
|-------------------------------------------------------------------------- 
|"this_is_#string"| 123 |{"str11_in#map":1,"str21_in#map":2, "str31_in#map": 31}|... 
|"this_is_#string"| 456 |{"str12_in#map":1,"str22_in#map":2, "str32_in#map": 32}|... 
|"this_is_#string"| 789 |{"str13_in#map":1,"str23_in#map":2, "str33_in#map": 33}|... 
|-------------------------------------------------------------------------- 

私は、文字列とマップタイプ のすべての列からいくつかの「_」などの文字や「#」を削除したいので結果 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に変換して作業したり、データフレームで作業したりするのが良いかどうかはわかりません。

また、最良の方法で異なる列タイプの正規表現を処理する方法がわかりません(私はという文字を使用しています)。 そして、私は次のように列名を使用しないようにしようと、これらの2つのタイプ(文字列、およびマップ)のすべての列に対してこのアクションを実行したいと思います:

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... 
} 

これを実行するには、いずれかの簡単な解決策はありますか?

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が処理するための文字列型の列: おかげ

答えて

3

1つのオプションは、文字列型の列と個別マップ型の列を処理するために2つのUDFを定義することである

def remove_string: String => String = _.replaceAll("[_#]", "") 
def remove_string_udf = udf(remove_string) 

2)UDFマップタイプの列を処理する:

def remove_map: Map[String, Int] => Map[String, Int] = _.map{ case (k, v) => k.replaceAll("[_#]", "") -> v } 
def remove_map_udf = udf(remove_map) 

3)udfsを対応するcoそれをきれいにする欄:

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

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

こんにちは@Psidom、ヒントありがとうかもしれません。これはうまくいくようですが、この方法では、Dataframeのすべての列をマップする必要があります。一般的な使用法を探していました。おそらくそれはまっすぐではありません..とにかく投票してください、tx –

+0

こんにちは@Psidom、何らかの変更によって、def def_map:.. 'のようなテンプレート関数を作成する方法があります:' def remove_map [T]:Map [ String、T] => Map [String、T] = '私はいくつかのアプローチを試みましたが、それらのどれかが機能しています。このwuldは、 'Map 'の組み合わせごとに1つずつ、複数の関数を持つことを避けます。 –

+0

可能かどうかわかりません。別の質問をして有益な答えを描くことができるかどうかを検討する価値があるかもしれません。 – Psidom

関連する問題