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-Key: 514201

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

Printed on: April 19, 2024 at 10:04 o'clock

Mitglied: 141861
141861 Nov 12, 2019 updated at 21:16:43 (UTC)
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
Member: SeaStorm
SeaStorm Nov 12, 2019 at 21:16:21 (UTC)
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
Member: Fennek11
Fennek11 Nov 12, 2019 updated at 22:33:42 (UTC)
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)
    }
Member: humpe99
humpe99 Nov 13, 2019 at 08:00:32 (UTC)
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!
Mitglied: 141815
Solution 141815 Nov 13, 2019 updated at 09:27:40 (UTC)
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()
Member: humpe99
humpe99 Nov 13, 2019 at 10:57:46 (UTC)
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!!!