2016-09-14 10 views
1

Ich habe mehrere Dateien, die jeweils mehrere hoch verschachtelte JSON Zeilen. Die zwei ersten Zeilen einer solchen Datei sehen so aus:Mehrere Jsons zu csv

{ 
"u":"28", 
"evv":{ 
     "w":{ 
      "1":400, 
      "2":{ 
       "i":[{ 
         "l":14, 
         "c":"7", 
         "p":"4" 
         } 
        ] 
       } 
      } 
     } 
} 
{ 
"u":"29", 
"evv":{ 
     "w":{ 
      "3":400, 
      "2":{ 
       "i":[{ 
         "c":14, 
         "y":"7", 
         "z":"4" 
         } 
        ] 
       } 
      } 
     } 
} 

sie sind eigentlich Zeilen, ich habe sie hier nur so für mehr Sichtbarkeit geschrieben.

Meine Frage ist folgende:

Gibt es eine Möglichkeit alle diese Dateien auf einen (oder mehrere, das heißt eine pro Datei) CSV/Excel zu konvertieren ...?

Gibt es eine einfache Art und Weise, die nicht Dutzende Schreiben erfordert, oder Hunderte von Zeilen in Python, die spezifisch für meine Datei, alle diese Dateien auf einen (oder mehr, dh eine pro Datei) zu konvertieren csv/Excel ...? Ein Beispiel wäre die Verwendung einer externen Bibliothek, eines Skripts ..., das diese bestimmte Aufgabe unabhängig von den Namen der Felder abwickelt.

Die Falle ist, dass einige Elemente nicht in jeder Zeile erscheinen. Für den Schlüssel "i" haben wir zum Beispiel 3 Felder (l, c, p) im ersten json und 3 im zweiten (c, y, z). Im Idealfall sollte der CSV so viele Spalten wie möglich enthalten (zB ev.w.2.il, evv.w.2.ic, evv.w.2.ip, evv.w.2.iy, evvw.w.). 2.iz) auf das Risiko von (vielen) Nullwerten pro CSV-Zeile.

Eine mögliche csv Ausgabe für dieses Beispiel würde die folgenden Spalten:

u, evv.w.1, evv.w.3, evv.w.2.i.l, evv.w.2.i.c, evv.w.2.i.p, evv.w.2.i.y, evv.w.2.i.z 

Jede Idee/Referenz ist willkommen :)

Dank

+0

Ja, es ist möglich - Ich empfehle, bei Python sucht [json] (https://docs.python.org/2/library/json.html) und [csv] (https://docs.python.org/2/library/csv.html) Module, und versuche, ein Skript zu schreiben, das das macht, was du willst. Komm zurück, wenn du nicht weiterkommst und wir helfen dir dein Programm zu debuggen –

+0

Bitte bearbeiten Sie Ihre Frage und zeigen Sie, was die CSV-Datei für die Beispieldaten enthalten soll und den Code, den Sie geschrieben haben, um es selbst zu tun. – martineau

+0

@HaydenSiff, ich bin mir der Existenz dieser beiden Module bewusst, und Ich weiß, dass ich sie benutzen kann, um e zu machen Genau was ich will, auch wenn es sehr umständlich sein kann. Meine Frage ist, ob ein Skript, das tut, was ich will, bereits vor – Salem

Antwort

1

Nein, es gibt keine Allzweck Programm, das genau das tut, was für Sie fragen.

Sie können jedoch ein Python-Programm schreiben, das es tut.

Dieses Programm könnte tun, was Sie wollen. Es hat keinen Code speziell für Ihre Schlüsselnamen, aber es ist spezifisch für Ihr Dateiformat.

  • Es kann mehrere Dateien in der Befehlszeile erfordern.
  • Jede Datei hat vermutlich ein JSON-Objekt pro Zeile.
  • Es flacht das JSON-Objekt ab und verbindet die Labels mit "."

 

import fileinput 
import json 
import csv 


def flattify(d, key=()): 
    if isinstance(d, list): 
     result = {} 
     for i in d: 
      result.update(flattify(i, key)) 
     return result 
    if isinstance(d, dict): 
     result = {} 
     for k, v in d.items(): 
      result.update(flattify(v, key + (k,))) 
     return result 
    return {key: d} 

total = [] 
for line in fileinput.input(): 
    if(line.strip()): 
     line = json.loads(line) 
     line = flattify(line) 
     line = {'.'.join(k): v for k, v in line.items()} 
     total.append(line) 

keys = set() 
for d in total: 
    keys.update(d) 

with open('result.csv', 'w') as output_file: 
    output_file = csv.DictWriter(output_file, sorted(keys)) 
    output_file.writeheader() 
    output_file.writerows(total) 
+0

Erstaunlich, danke :) Ich glaube nicht, dass dies behandelt mehrere Einträge in einer Liste in einem JSON (Beispiel evv.w.2.i.Eine Möglichkeit, dies zu tun wäre, um so viele Spalten wie benötigt zum Beispiel zu erstellen: ' Wenn isinstance (d, Liste): d = {str (i): j für i, j in enumerate (d)} zurück flattentify (d, Schlüssel = Schlüssel) ' – Salem

1

Bitte überprüfen Sie, ob diese (python3) Lösung funktioniert für dich.

import json 
import csv 

with open('test.json') as data_file: 
    with open('output.csv', 'w', newline='') as fp: 
     for line in data_file: 
      data = json.loads(line) 
      output = [[data['u'], data['evv']['w'].get('1'), data['evv']['w'].get('3'), 
         data['evv']['w'].get('2')['i'][0].get('l'), data['evv']['w'].get('2')['i'][0].get('c'), 
         data['evv']['w'].get('2')['i'][0].get('p'), data['evv']['w'].get('2')['i'][0].get('y'), 
         data['evv']['w'].get('2')['i'][0].get('z')]] 
      a = csv.writer(fp, delimiter=',') 
      a.writerows(output) 

test.json

{ "u": "28", "evv": {  "w": {   "1": 400,   "2": {    "i": [{     "l": 14,     "c": "7",     "p": "4"    }]   }  } }} 
{"u":"29","evv":{  "w":{   "3":400,   "2":{     "i":[{      "c":14,      "y":"7",      "z":"4"      }      ]     }   }  }} 

Ausgang

python3 pyprog.py 
[email protected] ~/P/pyprog> more output.csv 
28,400,,14,7,4,, 
29,,400,,14,,7,4 
Verwandte Themen