2017-12-07 11 views
0

のNUMにaccrodingいくつかの行に分析一行をします。データセットの行タイプは(文字列、文字列、文字列、Map [文字列、String])、Map.keysの数は1から3までです。したがって、1行は(文字列、文字列、文字列、 v)。 (:何百万、数百mydatasetの1行):どのように私は、データセットを読んで、それを処理しようとしていますmap.keys

val a = ("111","222","333",Map("k1"->"v1","k2"->"v2")) 

予想される出力:

("111","222","333","k1","v1") 
("111","222","333","k2","v2") 

しかし、大きなをこのような

var arr = new ArrayBuffer[Array[String]]() 
myDataset.collect.foreach{ 
f:(String,String,String,Map[String,String]) => 
    val ma = f._4 
    for((k,v)<-ma) { 
     arr += Array(f._1,f._2,f._3,k,v) 
    } 
} 

Orgdata: 私は実際には次のようにコードを使用して実現しますデータはOOMの問題を引き起こすので、これを達成する他の方法はありますか? OOMを避けるためにコードを最適化する方法は?

+1

それはあなたが大量のデータを持っている場合は、 'collect'を避けるために持っていることは言うまでもないです。また、サンプル入力と期待される出力を追加してください。 – philantrovert

答えて

1

あなただけexplodeマップの列と、その後爆発の列を選択することができます。

val df = sc.parallelize(Array(
    ("111","222","333",Map("k1"->"v1","k2"->"v2")) 
)).toDF("a", "b", "c", "d") 

df.select($"*", explode($"d")) 
    .select("a", "b", "c" ,"key", "value") 
    .as[(String, String, String, String, String)] 
    .first 
// (String, String, String, String, String) = (111,222,333,k1,v1) 
関連する問題