7

में ऐरे कॉलम एक्सेस करें स्पार्क डेटाफ्रेम में एरे [डबल] प्रकार का कॉलम होता है। जब मैं इसे मानचित्र() फ़ंक्शन में वापस लाने का प्रयास करता हूं तो यह क्लासकास्ट अपवाद अपवाद फेंक देता है। निम्नलिखित स्कैला कोड अपवाद उत्पन्न करता है।स्पार्क

case class Dummy(x:Array[Double]) 
val df = sqlContext.createDataFrame(Seq(Dummy(Array(1,2,3)))) 
val s = df.map(r => { 
    val arr:Array[Double] = r.getAs[Array[Double]]("x") 
    arr.sum 
}) 
s.foreach(println) 

अपवाद

java.lang.ClassCastException: scala.collection.mutable.WrappedArray$ofRef cannot be cast to [D 
    at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$anonfun$1.apply(<console>:24) 
    at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$anonfun$1.apply(<console>:23) 
    at scala.collection.Iterator$$anon$11.next(Iterator.scala:328) 
    at scala.collection.Iterator$class.foreach(Iterator.scala:727) 
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1157) 
    at org.apache.spark.rdd.RDD$$anonfun$foreach$1$$anonfun$apply$28.apply(RDD.scala:890) 
    at org.apache.spark.rdd.RDD$$anonfun$foreach$1$$anonfun$apply$28.apply(RDD.scala:890) 
    at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1848) 
    at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1848) 
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66) 
    at org.apache.spark.scheduler.Task.run(Task.scala:88) 
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:214) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 

कैम किसी ने मुझसे स्पष्टीकरण दें कि यह काम नहीं करता है? इसके बजाय मुझे क्या करना चाहिए? मैं स्पार्क 1.5.1 और स्केला 2.10.6

धन्यवाद

उत्तर

19

ArrayType एक scala.collection.mutable.WrappedArray के रूप में एक में प्रतिनिधित्व किया है उपयोग कर रहा हूँ। उदाहरण के लिए आप

val arr: Seq[Double] = r.getAs[Seq[Double]]("x") 

या

val i: Int = ??? 
val arr = r.getSeq[Double](i) 

या यहाँ तक कि का उपयोग कर इसे निकाल सकते हैं:

import scala.collection.mutable.WrappedArray 

val arr: WrappedArray[Double] = r.getAs[WrappedArray[Double]]("x") 

तो DataFrame अपेक्षाकृत पतली है तो पैटर्न मिलान एक बेहतर दृष्टिकोण हो सकता है:

import org.apache.spark.sql.Row 

df.rdd.map{case Row(x: Seq[Double]) => (x.toArray, x.sum)} 

हालांकि आपको यह ध्यान रखना होगा कि अनुक्रम का प्रकार अनचेक है।

स्पार्क में> = 1.6 आप भी Dataset इस प्रकार के रूप में उपयोग कर सकते हैं:

df.select("x").as[Seq[Double]].rdd