2016-01-27 7 views
8

Ich habe folgenden Datenrahmen in Funken:Elegante Json in Spark-abflachen

val test = sqlContext.read.json(path = "/path/to/jsonfiles/*") 
test.printSchema 
root 
|-- properties: struct (nullable = true) 
| |-- prop_1: string (nullable = true) 
| |-- prop_2: string (nullable = true) 
| |-- prop_3: boolean (nullable = true) 
| |-- prop_4: long (nullable = true) 
... 

Was würde ich tun möchte, ist diesen Datenrahmen glättet, so dass die prop_1 ... prop_n auf der obersten Ebene existiert. I.e.

test.printSchema 
root 
|-- prop_1: string (nullable = true) 
|-- prop_2: string (nullable = true) 
|-- prop_3: boolean (nullable = true) 
|-- prop_4: long (nullable = true) 
... 

Es gibt mehrere Lösungen für ähnliche Probleme. Das Beste, was ich finden kann, ist here gestellt. Die Lösung funktioniert jedoch nur, wenn properties vom Typ Array ist. In meinem Fall sind die Eigenschaften vom Typ StructType.

Ein alternativer Ansatz wäre so etwas wie:

test.registerTempTable("test") 
val test2 = sqlContext.sql("""SELECT properties.prop_1, ... FROM test""") 

Aber in diesem Fall habe ich jede Zeile explizit angeben, und das ist unelegant.

Was ist der beste Weg, um dieses Problem zu lösen?

Antwort

11

Wenn Sie sich nicht für eine rekursive Lösung dann in 1.6+ Punkt-Syntax mit Stern suchen sollte gut funktionieren:

val df = sqlContext.read.json(sc.parallelize(Seq(
    """{"properties": { 
     "prop1": "foo", "prop2": "bar", "prop3": true, "prop4": 1}}""" 
))) 

df.select($"properties.*").printSchema 
// root 
// |-- prop1: string (nullable = true) 
// |-- prop2: string (nullable = true) 
// |-- prop3: boolean (nullable = true) 
// |-- prop4: long (nullable = true) 

Leider ist dies in 1,5 und vor nicht.

In diesem Fall können Sie einfach erforderliche Informationen direkt aus dem Schema extrahieren. Sie finden ein Beispiel in Dropping a nested column from Spark DataFrame, das leicht angepasst werden sollte, um dieses Szenario und ein anderes (rekursives Schema in Python) Pyspark: Map a SchemaRDD into a SchemaRDD anzupassen.

Verwandte Themen