2017-05-24 2 views
1

Ich habe ein Dataset bestehend aus 7-8 Felder des Typs String, Int & Float.Spark - Schema programmgesteuert mit verschiedenen Datentypen erstellen

Am versuchen Schema von programmatischen Ansatz zu schaffen, indem diese mit:

val schema = StructType(header.split(",").map(column => StructField(column, StringType, true))) 

und Kartierung es dann Typ Zeile wie:

val dataRdd = datafile.filter(x => x!=header).map(x => x.split(",")).map(col => Row(col(0).trim, col(1).toInt, col(2).toFloat, col(3), col(4) ,col(5), col(6), col(7), col(8))) 

Aber nach Datenrahmen zu schaffen, wenn ich verwende DF.show () Es gibt Fehler für das Integer-Feld.

So wie solches Schema zu schaffen, in dem wir mehrere Datentypen im Datensatz

Antwort

1

Das Problem, das Sie in Ihrem Code haben müssen, ist, dass Sie all Felder wie String zuweisen.

Vorausgesetzt, dass Sie in der Kopfzeile nur den Namen der Felder haben, können Sie den Typ nicht erraten.

Nehmen wir an, dass die Header-Zeichenfolge wie folgt

ist
val header = "field1:Int,field2:Double,field3:String" 

Dann sollte der Code

def inferType(field: String) = field.split(":")(1) match { 
    case "Int" => IntegerType 
    case "Double" => DoubleType 
    case "String" => StringType 
    case _ => StringType 
} 

val schema = StructType(header.split(",").map(column => StructField(column, inferType(column), true))) 

Für die Header-String Beispiel Sie

root 
|-- field1:Int: integer (nullable = true) 
|-- field2:Double: double (nullable = true) 
|-- field3:String: string (nullable = true) 

Auf der anderen Seite erhalten werden . Wenn es sich um einen Datenrahmen aus Text handelt, würde ich vorschlagen, dass Sie den Datenrahmen direkt aus der Datei selbst erstellen. Es ist sinnlos, es von einer RDD zu erstellen.

val fileReader = spark.read.format("com.databricks.spark.csv") 
    .option("mode", "DROPMALFORMED") 
    .option("header", "true") 
    .option("inferschema", "true") 
    .option("delimiter", ",") 

val df = fileReader.load(PATH_TO_FILE) 
+0

Aber die Header String ist nicht so und Daten sind wie 'dfs8768768, 65, 76,34, 234, dfgdg, 34,65 dfs8768768, 65, 76,34, 234, dfgdg, 34,65 ' – AJm

+0

Dann ist es unmöglich, aus dem Header zu wissen die Art der Daten, da sie nicht angegeben ist. – elghoto

+0

Dies ist die genauen Daten mit Kopf: 'Versteigert, bid, Bietzeit, Bieter, bidderrate, openbid, Preis, Artikel, daystolive 8213034715,15,12.373, Baman, 3,12,20, book1,5 8213034725, 65,21,33, thmpu, 2,64,75, watch1,9 8213034735,85,23,3, lovekush, 4,45,90, remote1,10 8213034745,115,44.44, jaipanee, 3,111,130, s3phone, 4' – AJm

1

der Strukturtyp Definieren erster:

val schema1 = StructType(Array(
    StructField("AcutionId", StringType, true), 
    StructField("Bid", IntegerType, false), 
    StructField("BidTime", FloatType, false), 
    StructField("Bidder", StringType, true), 
    StructField("BidderRate", FloatType, false), 
    StructField("OpenBid", FloatType, false), 
    StructField("Price", FloatType, false), 
    StructField("Item", StringType, true), 
    StructField("DaystoLive", IntegerType, false) 
)) 

dann jede Spalte angeben, die es sich in einer Reihe vorhanden b wird auf bestimmte Typen durch Umwandlung:

val dataRdd = datafile.filter(x => x!=header).map(x => x.split(",")) 
    .map(col => Row(
    col(0).trim, 
    col(1).trim.toInt, 
    col(2).trim.toFloat, 
    col(3).trim, 
    col(4).trim.toFloat, 
    col(5).trim.toFloat, 
    col(6).trim.toFloat, 
    col(7).trim, 
    col(8).trim.toInt) 
) 

Dann wird die Anwendung Schema zum RDD

val auctionDF = spark.sqlContext.createDataFrame(dataRdd,schema1) 
Verwandte Themen