humpe99
Goto Top

Verschachteltes JSON in CSV umwanden

Hallo zusammen,

Das folgende JSON-File sollte in ein CSV-File umgewandelt werden:

{
    "results": [  
        {
            "statement_id": 0,  
            "series": [  
                {
                    "name": "measurements",  
                    "columns": [  
                        "time",  
                        "node",  
                        "sensor",  
                        "unit",  
                        "value"  
                    ],
                    "values": [  
                        [
                            "2019-11-12T18:32:33.416Z",  
                            "4462",  
                            "sensirion-sht35-humidity",  
                            "%",  
                            94.4609750514992
                        ],
                        [
                            "2019-11-12T18:32:33.416Z",  
                            "4462",  
                            "sensirion-sht35-temperature",  
                            "°C",  
                            -1.5537499046311112
                        ],
                        [
                            "2019-11-12T18:33:04.583Z",  
                            "2699",  
                            "sensirion-sht35-humidity",  
                            "%",  
                            98.73502708476387
                        ],
                        [
                            "2019-11-12T18:33:04.583Z",  
                            "2699",  
                            "sensirion-sht35-temperature",  
                            "°C",  
                            -3.2173647669184433
                        ]
                    ]
                }
            ]
        }
    ]
}

Schlussendlich soll das etwa so aussehen:

time,node,sensor,unit,value
2019-11-12T18:32:33.416Z,4462,sensirion-sht35-humidity,%,94.4609750514992
2019-11-12T18:32:33.416Z,4462,sensirion-sht35-temperature,°C,-1.5537499046311112
2019-11-12T18:33:04.583Z,2699,sensirion-sht35-humidity,%,98.73502708476387
2019-11-12T18:33:04.583Z,2699,sensirion-sht35-temperature,°C, -3.2173647669184433

Das ganze muss mit Python erfolgen - und meine Erfahrung mit Python ist übersichtlich bis inexistent. Mit Google habe ich einige Ansätze gefunden - die aber in meinem Fall alle daran scheitern, dass das JSON-File verschachtelt ist...

Danke für jeden Input!

Gruss, Humpe

Content-ID: 514201

Url: https://administrator.de/contentid/514201

Ausgedruckt am: 26.11.2024 um 09:11 Uhr

141861
141861 12.11.2019 aktualisiert um 22:16:43 Uhr
Goto Top
Hallo,

ein JSON File besteht ja letztendlich nur aus Text den man simple parsen kann.
Die Standardbibliothek von Python enthält sogar einen JSON Parser. Einfacher gehts nicht mehr. face-wink

https://www.w3schools.com/python/python_json.asp

Falls du es immer noch nicht hinbekommen solltest, dann bitte mal dein Code posten.

VG
SeaStorm
SeaStorm 12.11.2019 um 22:16:21 Uhr
Goto Top
Hi

und was genau hast du da bisher gemacht?
Kann ja nicht viel sein. Python hat mit seiner JSON library es so einfach gemacht wie es nur geht.
Was du da machen willst braucht wohl keine 20 Zeilen in Python
Fennek11
Fennek11 12.11.2019 aktualisiert um 23:33:42 Uhr
Goto Top
Mit Powershell:
$Con = get-content C:\Users\xxxx\Desktop\Admin.json.txt | Convertfrom-Json
$Ret = $f[1].results
$ser = $Ret.series
foreach ($v in $ser.values) {
    Write-Host ($v)
    }
humpe99
humpe99 13.11.2019 um 09:00:32 Uhr
Goto Top
Danke! Auf den JSON-Parser bin ich auch bereits gestossen. Mein Script sieht folgendermassen aus:

#!/usr/local/bin/python
import json
import csv

def get_leaves(item, key=None):
    if isinstance(item, dict):
        leaves = 
        for i in item.keys():
            leaves.extend(get_leaves(item[i], i))
        return leaves
    elif isinstance(item, list):
        leaves = 
        for i in item:
            leaves.extend(get_leaves(i, key))
        return leaves
    else:
        return [(key, item)]


with open('input.json') as f_input, open('output.csv', 'w') as f_output:  
    csv_output = csv.writer(f_output)
    write_header = True

    for entry in json.load(f_input):
        leaf_entries = sorted(get_leaves(entry))

        if write_header:
            csv_output.writerow([k for k, v in leaf_entries])
            write_header = False

        csv_output.writerow([v for k, v in leaf_entries])

Das Resultat sieht dann so aus:
""  
results
… ähnelt also nur sehr entfernt dem gewünschten Resultat …

Ich habe auch einfachere Scripts ausprobiert:

#!/usr/local/bin/python
import csv, json, sys

inputFile = open('input.json') #open json file  
outputFile = open('output.csv', 'w') #load csv file  

data = json.load(inputFile) #load json content
inputFile.close() #close the input file    
  
output = csv.writer(outputFile) #create a csv.write    
output.writerow(data.keys())  # header row    
  
for row in data:
   output.writerow(row.values()) #values row

Da gab es dann folgende Fehlermeldung:

[home] $ python json_to_csv.py
Traceback (most recent call last):
  File "json_to_csv.py", line 11, in <module>  
    output.writerow(data.keys())  # header row
KeyError: 0

Ich möchte als mildernden Umstand die Tatsache ins Feld führen, dass ich alle paar Schaltjahre mal was Kleines programmieren muss und es sich um meinen ersten Kontakt mit Python überhaupt handelt...

Danke weiterhin für jede Hilfe!
141815
Lösung 141815 13.11.2019 aktualisiert um 10:27:40 Uhr
Goto Top
Ein und Ausgabedatei in den Open-Anweisungen anpassen feddich.
#!/usr/local/bin/python
import csv, json

inputFile = open('test.json') #open json file  
outputFile = open('test.csv', 'w') #load csv file  

data = json.load(inputFile) #load json content
inputFile.close() #close the input file    
  
output = csv.writer(outputFile) #create a csv.write    
output.writerow(data['results']['series']['columns'])  
  
for row in data['results']['series']['values']:  
   output.writerow(row)

outputFile.close()
humpe99
humpe99 13.11.2019 um 11:57:46 Uhr
Goto Top
Danke für den Vorschlag! Sofort umgesetzt, leider noch nicht ganz erfolgreich, die folgende Fehlermeldung ist aufgetreten.

[home] $ python j2c.py
Traceback (most recent call last):
  File "j2c.py", line 9, in <module>  
    strCSV += ";".join(str(e) for e in itm) + "\r\n"  
  File "j2c.py", line 9, in <genexpr>  
    strCSV += ";".join(str(e) for e in itm) + "\r\n"  
UnicodeEncodeError: 'ascii' codec can't encode character u'\xb0' in position 0: ordinal not in range(128)  

Ich habe dem Code dann noch den folgenden Abschnitt vorangestellt:

import sys
reload(sys)
sys.setdefaultencoding('utf8')  

...und es geht!

Danke für die Unterstützung!!!