2017-07-25 5 views
0

Mein Ziel ist es, ein DataFrame in ein gültiges JSONArray von JSONObject zu konvertieren.So konvertieren Sie ein Spark-Datenframe in JSONObject

ich zur Zeit mit:

val res = df.toJSON.collect() 

Aber ich bin immer ein Array [String] - Array von JSON-Strings entkommen, das heißt:

["{\"url\":\"http://www.w3schools.com/html/html_form_action.asp?user=123\",\"subnet\":\"32.2.208.1\",\"country\":\"\",\"status_code\":\"200\"}"] 

Ich suche eine Weise, diese Zeichenfolgen in tatsächliche JSONObjects zu konvertieren, fand ich ein paar Lösung, die find and replace characters vorgeschlagen, aber ich bin auf der Suche nach etwas sauberer.

Ich habe versucht, jede Zeichenfolge zu einem JSONObject mit org.json Bibliothek zu konvertieren, aber offensichtlich ist es kein Serializable-Objekt.

Irgendwelche Vorschläge? jede schnelle Scala JSON-Bibliothek, die funktionieren kann?

Oder wie im Allgemeinen vorgeschlagen wird, mit der toJSON-Methode zu arbeiten.

aktualisiert

Das ist ein bisschen verschwenderisch, aber diese Option funktioniert für mich:

val res = df.toJSON.map(new JSONObject(_).toString).collect() 

Da JSONObject ist nicht serializable - ich sein toString verwenden kann, ein gültiges JSON-Format zu erhalten.

Wenn Sie noch Vorschläge haben, wie ich es verbessern kann - lassen Sie es mich wissen.

+0

Können Sie mit Beispieldaten Ihres Datenrahmens aktualisieren? –

+0

Ich bekomme diese Zitate nicht entkommen, wenn ich 'toJSON' verwende. Ich benutze Spark 1.6. – philantrovert

+0

@philantrovert, das ist seltsam, wir verwenden Spark 1.6.1. Alle Fragen, die ich online zu diesem Thema sah, gaben an, dass das Format das gleiche ist. – LiranBo

Antwort

0

Sie könnten spray-json verwenden, um die Zeichenfolge in eine Fallklasse zu analysieren:

import spray.json._ 
import DefaultJsonProtocol._ 
case class Data(url: String, subnet: String, country: String, status_code: String) 
implicit val dataFormat = jsonFormat4(Data) 
val source = Array("{\"url\":\"http://www.w3schools.com/html/html_form_action.asp?user=123\",\"subnet\":\"32.2.208.1\",\"country\":\"\",\"status_code\":\"200\"}") 
val data = source(0).parseJson.convertTo[Data] 
+0

Ich erwog auch die Option, Fallklassen zu verwenden, aber es gibt über 80 verschachtelte Felder. Es wäre also ziemlich komplex, einen zu erstellen. Ich hatte gehofft, irgendwie das Datenrahmenschema zu verwenden. – LiranBo

+0

Wenn Sie nur einige Daten aus dem JSON herausholen möchten, müssen Sie nur die Fallklassenhierarchie für die benötigten Bits definieren.zB würde das obige auch mit 'case class Data (url: String, subnet: String) funktionieren. – jamborta

+0

Ja, mir ist bewusst, aber ich brauche fast die gesamte Struktur. Ich verwende Fallklassen in einigen inneren UDFs, um einige der Daten zu manipulieren. aber das Ergebnis sollte fast alles beinhalten. – LiranBo

0

Sie die DataframeWriter Klasse verwenden können.

Dies kann mehrere Teile Dateien erstellen, wenn die Ausgabedatei eine Anzahl von Datensätzen/Partitionen hat. Sie können dann ein einfaches Merge-Dienstprogramm schreiben, um Teiledateien im hdfs/lokalen Dateisystem zu kombinieren.

Im Fall Ausgabe ist eine kleine Datei - Sie coalesce verwenden können()

df.coalesce(1).write.json(path) 

Sie können es dann in einen DF zurückgelesen.

+0

Danke für den Vorschlag, aber die Leistung ist ein ernstes Problem hier. Ich kann die Daten nicht in Dateien schreiben und sie dann erneut lesen. – LiranBo

Verwandte Themen