2016-12-08 4 views
2

Ich habe eine Array Array-Liste genannt, die wie dieseTuple zu Datenrahmen in Funken scala

arraylist: Array[(String, Any)] = Array((id,772914), (x4,2), (x5,24), (x6,1), (x7,77491.25), (x8,17911.77778), (x9,225711), (x10,17), (x12,6), (x14,5), (x16,5), (x18,5.0), (x19,8.0), (x20,7959.0), (x21,676.0), (x22,228.5068871), (x23,195.0), (x24,109.6015511), (x25,965.0), (x26,1017.79043), (x27,2.0), (Target,1), (x29,13), (x30,735255.5), (x31,332998.432), (x32,38168.75), (x33,107957.5278), (x34,13), (x35,13), (x36,13), (x37,13), (x38,13), (x39,13), (x40,13), (x41,7), (x42,13), (x43,13), (x44,13), (x45,13), (x46,13), (x47,13), (x48,13), (x49,14.0), (x50,2.588435821), (x51,617127.5), (x52,414663.9738), (x53,39900.0), (x54,16743.15781), (x55,105000.0), (x56,52842.29076), (x57,25750.46154), (x58,8532.045819), (x64,13), (x66,13), (x67,13), (x68,13), (x69,13), (x70,13), (x71,13), (x73,13), (... 

ich es auf einen Datenrahmen mit zwei Spalten „ID“ und den Wert konvertieren möge aussieht. Fo Theis der Code ich verwende ist

val df = sc.parallelize(arraylist).toDF("Names","Values") 

Jedoch habe ich eine Störung erhalte

java.lang.UnsupportedOperationException: Schema for type Any is not supported 

Wie kann ich dieses Problem zu überwinden?

Antwort

4

Nachricht sagt Ihnen alles :) Alle als eine Art Spalte von Datenrahmen wird nicht unterstützt. Any Typ kann durch nulls als zweites Element eines Tupels

ändern Arraylist Typ Array[(String, Int)] verursacht werden (wenn Sie es manuell tun, wenn sie von Scala abgezogen wird, überprüfen Sie dann für Nullen und ungültige Werte des zweiten Elements) oder manuell erstellen schema:

import org.apache.spark.sql.types._ 
import org.apache.spark.sql._ 

val arraylist: Array[(String, Any)] = Array(("id",772914), ("x4",2.0), ("x5",24.0)); 

val schema = StructType(
    StructField("Names", StringType, false) :: 
    StructField("Values", DoubleType, false) :: Nil) 
val rdd = sc.parallelize (arraylist).map (x => Row(x._1, x._2.asInstanceOf[Number].doubleValue())) 

val df = sqlContext.createDataFrame(rdd, schema) 

df.show() 

Hinweis: createDataFrame erfordert RDD [Reihe], so dass ich die Umwandlung RDD von Tupels RDD von Row

+0

Endlich nach stundenlangem Hämmern. Wird ewig dankbar sein :) –

+0

@RajarshiBhadra Mapping RDD [Row] als heikel, habe ich auch darüber zunächst vergessen;) Nur nach einer Weile habe ich meine Codes geprüft und sehen Sie den Unterschied –

1

das Problem (wie bereits erwähnt) ist, dass jede keine juristische Art ist zum Datenrahmen. Im Allgemeinen sind legale Typen primitive Typen (Byte, Int, Boolesch, String, Doppel usw.), Strukturen von legalen Typen, Arrays von legalen Typen und Karten von legalen Typen und verdopple den zweiten Wert des Tupels. Wenn Sie stattdessen nur doppelt verwenden, sollte es richtig funktionieren.

Sie können dies auf zwei Arten tun: 1. Stellen Sie sicher, dass das Original-Array hat nur doppelt (zB durch .0 am Ende jeder Integer-Zugabe, wenn Sie es schaffen) oder durch eine Besetzung zu tun 2. Erzwingen der Schema:

import org.apache.spark.sql.types._ 
val schema = new StructType() 
schema.add(StructField("names",StringType)) 
schema.add(StructField("values",DoubleType)) 
val rdd = sc.parallelize(arraylist).map (x => Row(x._1, x._2.asInstanceOf[Number].doubleValue())) 
val df = spark.createDataFrame(rdd,schema) 
+0

Ich erhalte diesen Fehler Import org.apache.spark.sql.types._ : 39: Fehler: Überladener Methodenwert gilt mit Alternativen: (Felder: Array [org.apache.spark.sql.types.StructField]) org.apache.spark. sql.types.StructType (Felder: java.util.List [org.apache.spark.sql.types.StructField]) org.apache.spark.sql.types.StructType (Felder: Seq [org.apache .spark.sql.types.StructField]) org.apache.spark.sql.types.StructType kann nicht auf() val-Schema angewendet werden = StructType() ^ –

+0

@RajarshiBhadra Das zweite Argument von StructField sollte nicht '()' haben - siehe meine Antwort –

+0

Sorry, das passiert, wenn ich Freeform schreibe ... Bearbeitet um zu reparieren ... –