मैं एक डेटासेट पढ़ने और इसे संसाधित करने की कोशिश कर रहा हूं; डेटासेट पंक्ति प्रकार है (स्ट्रिंग, स्ट्रिंग, स्ट्रिंग, मैप [स्ट्रिंग, स्ट्रिंग]), Map.keys की संख्या 1 से 3 तक है, इसलिए एक पंक्ति 1-3 पंक्तियाँ बन जाएगी जैसे (स्ट्रिंग, स्ट्रिंग, स्ट्रिंग, k, वी)। मैं वास्तव में इसे निम्नानुसार कोड का उपयोग करके महसूस करता हूं:

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

इस तरह ऑर्गडेटा (mydataset में एक पंक्ति: सैकड़ों लाखों):

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

अपेक्षित उत्पादन:

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

लेकिन बड़ा डेटा OOM समस्या का कारण बनता है, तो क्या इसे पूरा करने के अन्य तरीके हैं? या ओओएम से बचने के लिए मेरे कोड को कैसे अनुकूलित करें?

0
JasonTian 7 पद 2017, 11:40

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)
1
philantrovert 7 पद 2017, 13:38