2015-01-12 2 views
5

Sono molto nuovo ai file Json. Se ho un file JSON con più oggetti JSON, come segue:più oggetti Json in un file estratto da python

{"ID":"12345","Timestamp":"20140101", "Usefulness":"Yes", 
    "Code":[{"event1":"A","result":"1"},…]} 
{"ID":"1A35B","Timestamp":"20140102", "Usefulness":"No", 
    "Code":[{"event1":"B","result":"1"},…]} 
{"ID":"AA356","Timestamp":"20140103", "Usefulness":"No", 
    "Code":[{"event1":"B","result":"0"},…]} 
… 

Voglio estrarre tutto "Timestamp" e "utilità" in un frame di dati:

Timestamp Usefulness 
0 20140101  Yes 
1 20140102  No 
2 20140103  No 
… 

Qualcuno sa un generale modo di affrontare tali problemi? Grazie!

+1

avere un singolo array json contenente tutto l'oggetto json sarebbe molto più semplice – njzk2

risposta

8

utilizzare un array JSON, nel formato:

[ 
{"ID":"12345","Timestamp":"20140101", "Usefulness":"Yes", 
    "Code":[{"event1":"A","result":"1"},…]}, 
{"ID":"1A35B","Timestamp":"20140102", "Usefulness":"No", 
    "Code":[{"event1":"B","result":"1"},…]}, 
{"ID":"AA356","Timestamp":"20140103", "Usefulness":"No", 
    "Code":[{"event1":"B","result":"0"},…]}, 
... 
] 

Poi importarlo nel codice Python

json=open('file.json') 

data = json.load(json) 

Ora il contenuto dei dati è una matrice con i dizionari che rappresenta ciascuno degli elementi.

È possibile accedere facilmente, vale a dire:

data[0]["ID"] 
+9

Questo è interessante, ma impedisce di utilizzare il file come un flusso infinito (ad esempio dati del file solo come log-app) e consuma molta più memoria . – exa

+0

In alcuni casi, un MOLTO ... come ... più di quale memoria ho. –

0

Mentre analizzi gli oggetti, hai a che fare con i dizionari. È possibile estrarre i valori necessari cercando tramite chiave. Per esempio. value = jsonDictionary['Usefulness'].

È possibile eseguire il ciclo degli oggetti json utilizzando un ciclo for. ad esempio:

for obj in bunchOfObjs: 
    value = obj['Usefulness'] 
    #now do something with your value, e.g insert into panda.... 
0

Così, come è stato detto in un paio di commenti contenenti i dati in un array è più semplice, ma la soluzione non scala bene in termini di efficienza come i dati aumenta la dimensione. Dovresti davvero usare un iteratore solo quando vuoi accedere a un oggetto casuale nell'array, altrimenti i generatori sono la strada da percorrere. Di seguito ho prototipato una funzione di lettura che legge individualmente ciascun oggetto JSON e restituisce un generatore.

L'idea di base è di segnalare al lettore di dividere il carattere di carrello "\ n" (o "\ r \ n" per Windows). Python può farlo con la funzione .readline().

import json 
def json_readr(file): 
    for line in open(file, mode="r"): 
     yield json.loads(line) 

Tuttavia, questo metodo funziona veramente solo quando il file viene scritto come lo avete - con ogni oggetto separati da un carattere di nuova riga. Di seguito ho scritto un esempio di uno scrittore che separa una serie di oggetti json e li salva su una nuova riga.

def json_writr(file, json_objects): 
    f = open(file, mode="w") 
    for jsonobj in json_objects: 
     jsonstr = json.dumps(jsonobj) 
     f.write(jsonstr+"\n") 
    f.flush() 
    f.close() 

Si potrebbe anche fare la stessa operazione con il file .writelines() e di lista

... 
    jsobjs = [json.dumps(j)+"\n" for j in json_objects] 
    f.writelines(jsobjs) 
... 

E se si voleva aggiungere i dati invece di scrivere un nuovo file basta cambiare modalità ' = "w" 'a' mode = "a" '.

Alla fine trovo che questo aiuti molto non solo la leggibilità quando provo ad aprire i file JSON nell'editor di testo, ma anche in termini di utilizzo della memoria in modo più efficiente.

In questa nota, se cambi idea a un certo punto e desideri estrarre una lista dal lettore, Python ti consente di inserire una funzione generatore all'interno di una lista e popolare automaticamente la lista.In altre parole, basta scrivere

lst = list(json_readr(file)) 

Spero che questo aiuti. Scusa se è stato un po 'prolisso.