CSV in JSON
Rilevamento del delimitatore, campi tra virgolette e inferenza dei tipi che non ti mangia i CAP.
Nulla di ciò che incolli lascia il tuo browser. L’allowlist connect-src ne fa una garanzia del browser anziché una promessa. Verificalo tu stesso
Converti un CSV in un array JSON di oggetti, usando la riga di intestazione come chiavi. I delimitatori vengono rilevati, i campi tra virgolette con virgole e a capo interni sono gestiti, e i nomi di colonna duplicati vengono rinominati anziché scartati.
L’inferenza dei tipi è disattivata per impostazione predefinita, ed è una scelta voluta.
Perché ogni valore è una stringa finché non dici il contrario
L’inferenza dei tipi è il punto in cui i convertitori CSV distruggono i dati. Un CSV non ha tipi, quindi il convertitore deve indovinare, e sbaglia in modi difficili da notare.
007 diventa 7 e il CAP è sparito. Un numero di telefono scritto come 1234567890123456789 supera ciò che un numero JavaScript può contenere e torna diverso. Un codice prodotto come 1E5 diventa 100000. Un valore NA diventa una stringa in una riga e l’intestazione di una colonna da un’altra parte.
Per questo il valore predefinito sono le stringhe. Attiva l’inferenza quando conosci i tuoi dati, e nota che anche allora gli zeri iniziali vengono conservati e qualsiasi valore che non sopravvivrebbe a un’andata e ritorno in float64 resta una stringa.
Le regole del CSV su cui tutti inciampano
- Virgolette
- RFC 4180: un campo che contiene una virgola, una virgoletta o un a capo viene racchiuso tra virgolette doppie, e una virgoletta interna viene raddoppiata. Questo parser lo legge correttamente, campi su più righe compresi.
- Delimitatori
- Virgola, punto e virgola, tabulazione e barra verticale vengono rilevati automaticamente contando le occorrenze fuori dalle virgolette nelle prime righe. L’Excel europeo scrive punti e virgola.
- Intestazioni duplicate
- Gli oggetti JSON non possono avere chiavi duplicate, quindi un nome di colonna ripetuto riceve un suffisso e la modifica viene segnalata. Scartarne uno sarebbe una perdita silenziosa di dati.
- Righe irregolari
- Una riga con meno campi dell’intestazione riceve dei null; una con più campi conserva gli extra sotto una chiave _extra. Entrambi i casi vengono segnalati con il numero di riga anziché riallineati in silenzio.
- Il byte order mark
- Viene tolto, e segnalato. Lasciato al suo posto diventa parte del nome della prima colonna, e ne esce un campo misteriosamente introvabile.
Ricostruire la struttura annidata
Se le tue intestazioni sono percorsi puntati, come in un CSV prodotto dal nostro stesso convertitore, attiva «espandi le intestazioni puntate» e l’annidamento viene ricostruito: address.city torna a essere un oggetto annidato anziché una chiave che contiene un punto.
How to do this in code
Convertire nel codice.
py Python
utf-8-sig toglie il BOM. dtype=str è il modo di impedire a pandas di trasformare 007 in 7.
import csv, json
# The standard library gives you strings, which is the honest default
with open('in.csv', newline='', encoding='utf-8-sig') as f:
rows = list(csv.DictReader(f))
print(json.dumps(rows, indent=2))
# pandas infers types, which is convenient and lossy
import pandas as pd
df = pd.read_csv('in.csv', dtype=str) # dtype=str turns inference OFF
records = df.to_dict(orient='records') js JavaScript
import Papa from 'papaparse';
const { data, errors } = Papa.parse(csv, {
header: true,
skipEmptyLines: true,
dynamicTyping: false, // leave it off; see the note above
}); sh Shell
# csvkit
in2csv data.csv | csvjson --indent 2 > data.json
# Or with Miller, which is a single binary
mlr --icsv --ojson cat data.csv Domande frequenti
- Conviene attivare l’inferenza dei tipi?
- Solo se conosci i dati. Ha ragione quasi sempre, e le eccezioni sono proprio i valori che non puoi permetterti di perdere: CAP, numeri di conto, codici articolo, numeri di telefono, tutto ciò che ha uno zero iniziale. Anche con l’inferenza attiva, questo strumento li lascia stare.
- Perché il nome della mia prima colonna è strano?
- Un byte order mark. Questo strumento lo toglie e lo dichiara. Un parser che non lo fa lascia un carattere invisibile all’inizio del nome, così le ricerche per quel nome falliscono senza un motivo visibile.
- Posso ottenere NDJSON invece di un array?
- Converti qui e poi usa la pagina NDJSON, che trasforma un array in un record per riga. È il formato migliore per tutto ciò che intendi trasmettere in streaming o a cui vuoi aggiungere righe.