JSON naar CSV in Python β€” DictWriter + pandas Voorbeelden

Β·Backend DeveloperΒ·Beoordeeld doorPriya SharmaΒ·Gepubliceerd

Gebruik de gratis JSON to CSV direct in je browser β€” geen installatie nodig.

JSON to CSV online uitproberen β†’

Vrijwel elke datapipeline stuit uiteindelijk op dezelfde stap: een API geeft JSON terug, maar de volgende afnemer β€” een spreadsheet, een importscript, een Redshift COPY-opdracht β€” heeft CSV nodig. Het converteren van JSON naar CSV in Python klinkt eenvoudig totdat u geneste objecten, inconsistente sleutels of datetime-waarden tegenkomt die speciale behandeling vereisen. Python biedt twee solide wegen: de ingebouwde json + csv modules voor scripts zonder afhankelijkheden, en pandas voor het afvlakken van geneste structuren en grotere datasets β€” of de online JSON naar CSV converter voor snelle eenmalige conversies zonder code. Deze gids behandelt beide aanpakken van begin tot eind, met uitvoerbare Python 3.8+ voorbeelden.

  • βœ“csv.DictWriter converteert een lijst van dicts naar CSV zonder afhankelijkheden β€” gebruik json.load() om te parsen, daarna writeheader() + writerows().
  • βœ“Open CSV-bestanden altijd met newline="" op Windows om lege rijen tussen datarijen te voorkomen.
  • βœ“pd.json_normalize() vlakt geneste JSON af naar een plat DataFrame voordat to_csv() wordt aangeroepen β€” verwerkt meerdere niveaus van nesting automatisch.
  • βœ“Geef index=False door aan DataFrame.to_csv() β€” zonder dit schrijft pandas een ongewenste rijnummerkolom.
  • βœ“Voor bestanden boven 500 MB gebruikt u ijson voor gestreamde JSON-verwerking in combinatie met csv.DictWriter voor constant geheugengebruik.

Wat is JSON naar CSV-conversie?

JSON naar CSV-conversie transformeert een array van JSON-objecten naar een tabelindeling waarbij elk object een rij wordt en elke sleutel een kolomkoptekst. JSON is hiΓ«rarchisch β€” objecten kunnen willekeurig diep nesten. CSV is plat β€” elke waarde staat in een rij-kolomraster. De conversie werkt soepel wanneer elk object dezelfde set van sleutels op het bovenste niveau deelt. Geneste objecten, arrays en inconsistente sleutels zijn waar het interessant wordt. De ruwe gegevens blijven identiek; alleen de structuur verandert.

Before Β· json
After Β· json
[{"order_id":"ord_91a3","total":149.99,"status":"shipped"},
 {"order_id":"ord_b7f2","total":34.50,"status":"pending"}]
order_id,total,status
ord_91a3,149.99,shipped
ord_b7f2,34.50,pending

csv.DictWriter β€” JSON naar CSV converteren zonder pandas

De csv-module wordt meegeleverd bij elke Python-installatie. Geen pip install, geen gedoe met virtuele omgevingen. csv.DictWriter neemt een lijst van dictionaries en schrijft elk als een CSV-rij, waarbij dict-sleutels worden gekoppeld aan kolomkopteksten. De fieldnames parameter bepaalt zowel de kolomvolgorde als welke sleutels worden opgenomen.

Python 3.8+ β€” minimaal json naar csv voorbeeld
import json
import csv

# Voorbeeld JSON-data β€” een array van bestelobjecten
json_string = """
[
  {"order_id": "ord_91a3", "product": "Wireless Keyboard", "quantity": 2, "unit_price": 74.99},
  {"order_id": "ord_b7f2", "product": "USB-C Hub", "quantity": 1, "unit_price": 34.50},
  {"order_id": "ord_c4e8", "product": "Monitor Stand", "quantity": 3, "unit_price": 29.95}
]
"""

records = json.loads(json_string)

with open("orders.csv", "w", newline="", encoding="utf-8") as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=records[0].keys())
    writer.writeheader()
    writer.writerows(records)

# orders.csv:
# order_id,product,quantity,unit_price
# ord_91a3,Wireless Keyboard,2,74.99
# ord_b7f2,USB-C Hub,1,34.50
# ord_c4e8,Monitor Stand,3,29.95

Dat newline="" argument bij open() is niet optioneel op Windows. Zonder dit krijgt u dubbele regelteruglooptekens β€” die verschijnen als lege rijen tussen elke datarij in Excel. Op macOS en Linux is het onschadelijk, dus neem het gewoon altijd op.

De bovenstaande code gebruikt json.loads() voor een string. Gebruik json.load() (zonder afsluitende s) bij het lezen van een bestandshandler. Dit verwarrt mensen voortdurend β€” de ene leest een string, de andere leest een bestandsobject.

Python 3.8+ β€” JSON-bestand lezen, CSV-bestand schrijven
import json
import csv

with open("server_metrics.json", encoding="utf-8") as jf:
    metrics = json.load(jf)  # json.load() voor bestandsobjecten

# Expliciete fieldnames bepalen de kolomvolgorde
columns = ["timestamp", "hostname", "cpu_percent", "memory_mb", "disk_io_ops"]

with open("server_metrics.csv", "w", newline="", encoding="utf-8") as cf:
    writer = csv.DictWriter(cf, fieldnames=columns, extrasaction="ignore")
    writer.writeheader()
    writer.writerows(metrics)

# Alleen de vijf opgegeven kolommen verschijnen, in exact die volgorde

Het instellen van extrasaction="ignore" laat stilzwijgend alle sleutels in de dicts vallen die niet in uw fieldnames-lijst staan. De standaardwaarde is "raise", wat een ValueError gooit als een dict een onverwachte sleutel heeft. Kies wat past bij uw tolerantie voor verrassingen.

Opmerking:csv.DictWriter vs csv.writer: DictWriter koppelt dict-sleutels automatisch aan kolomposities. csv.writer schrijft ruwe lijsten als rijen β€” u regelt de kolomvolgorde zelf. DictWriter is vrijwel altijd de juiste keuze voor JSON-naar-CSV omdat JSON-records al dictionaries zijn.

Python's csv module wordt geleverd met drie benoemde dialecten: excel (kommascheidingsteken, CRLF-regelafsluitingen β€” de standaard), excel-tab (tab-scheidingsteken, CRLF-afsluitingen) en unix (LF-regelafsluitingen, citeert alle niet-numerieke velden). Geef de dialectnaam door als het dialect argument aan csv.DictWriter. U kunt ook een aangepast dialect definiΓ«ren met csv.register_dialect() wanneer uw doelsysteem ongebruikelijke quote- of scheidingstekensregels heeft. Voor de meeste JSON-naar-CSV workflows is het excel dialect correct, maar schakel over naar unix bij het schrijven van bestanden die worden verwerkt door POSIX-tools zoals awk of sort.

Omgaan met niet-standaard types: datetime, UUID en Decimal

JSON van API's bevat vaak datums als ISO-strings, UUID's als strings met koppeltekens en geldbedragen als floats. Wanneer u deze naar Python-objecten parseert voor verwerking voordat u CSV schrijft, moet u ze terug naar strings omzetten. De csv module roept str() aan op elke waarde, dus de meeste types werken gewoon. Maar datetime-objecten leveren rommelige standaard tekenreeksrepresentaties op, en Decimal-waarden hebben expliciete opmaak nodig om wetenschappelijke notatie te vermijden.

Python 3.8+ β€” datetime en Decimal voorbereiden voor CSV-schrijven
import json
import csv
from datetime import datetime, timezone
from decimal import Decimal
from uuid import UUID

# Gesimuleerd geparsed API-antwoord met Python-types
transactions = [
    {
        "txn_id": UUID("a1b2c3d4-e5f6-7890-abcd-ef1234567890"),
        "created_at": datetime(2026, 3, 15, 9, 30, 0, tzinfo=timezone.utc),
        "amount": Decimal("1249.99"),
        "currency": "USD",
        "merchant": "CloudHost Inc.",
    },
    {
        "txn_id": UUID("b2c3d4e5-f6a7-8901-bcde-f12345678901"),
        "created_at": datetime(2026, 3, 15, 14, 12, 0, tzinfo=timezone.utc),
        "amount": Decimal("87.50"),
        "currency": "EUR",
        "merchant": "DataSync GmbH",
    },
]

def prepare_row(record: dict) -> dict:
    """Converteer niet-string types naar CSV-vriendelijke strings."""
    return {
        "txn_id": str(record["txn_id"]),
        "created_at": record["created_at"].isoformat(),
        "amount": f"{record['amount']:.2f}",
        "currency": record["currency"],
        "merchant": record["merchant"],
    }

with open("transactions.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["txn_id", "created_at", "amount", "currency", "merchant"])
    writer.writeheader()
    for txn in transactions:
        writer.writerow(prepare_row(txn))

# transactions.csv:
# txn_id,created_at,amount,currency,merchant
# a1b2c3d4-e5f6-7890-abcd-ef1234567890,2026-03-15T09:30:00+00:00,1249.99,USD,CloudHost Inc.
# b2c3d4e5-f6a7-8901-bcde-f12345678901,2026-03-15T14:12:00+00:00,87.50,EUR,DataSync GmbH

De prepare_row() functie is hier de juiste aanpak. In plaats van csv.DictWriter te leren omgaan met aangepaste types, normaliseert u elk record naar strings voor het schrijven. Ik geef de voorkeur aan het expliciet aanroepen van .isoformat() op datetime-objecten boven vertrouwen op str() β€” het uitvoerformaat is voorspelbaarder en downstream parsers verwerken ISO 8601 betrouwbaar.

Waarschuwing:Als u Decimal-waarden zonder opmaak doorlaat, kunnen zeer kleine of zeer grote getallen in wetenschappelijke notatie worden weergegeven (bijv. 1.5E+7). Formatteer Decimal altijd met een expliciete f-string zoals f"{value:.2f}" bij het schrijven van financiΓ«le gegevens naar CSV.

Een alternatief patroon voor pipelines met veel aangepaste types is het uitbreiden van json.JSONEncoder. Subclass het, overschrijf de default() methode om een JSON-serialiseerbare waarde terug te geven voor elk aangepast type, en geef de subclass dan door als het cls argument aan json.dumps(). Opnieuw coderen via de aangepaste encoder vóór het schrijven naar CSV normaliseert alle types in één stap zonder een per-rij prepare_row() aanroep. Het prepare_row() patroon hierboven is eenvoudiger voor eenmalige scripts; de JSONEncoder subclass aanpak schaalt beter wanneer hetzelfde domeinmodel met aangepaste types wordt gedeeld over meerdere pipelinestadia of microservices.

csv.DictWriter Parameters Referentie

De volledige constructor-signatuur is csv.DictWriter(f, fieldnames, restval="", extrasaction="raise", dialect="excel", **fmtparams). De meeste hiervan hebben redelijke standaardwaarden. De waarden die u daadwerkelijk aanpast zijn fieldnames, delimiter, en extrasaction.

Parameter
Type
Standaard
Beschrijving
f
file object
(verplicht)
Elk object met een write()-methode β€” doorgaans afkomstig van open()
fieldnames
sequence
(verplicht)
Lijst van sleutels die de kolomvolgorde in de CSV-uitvoer bepaalt
restval
str
""
Waarde die wordt geschreven wanneer een dict een sleutel uit fieldnames mist
extrasaction
str
"raise"
"raise" gooit ValueError bij extra sleutels; "ignore" laat ze stilletjes vallen
dialect
str / Dialect
"excel"
Voorgedefinieerde opmaakregels β€” "excel", "excel-tab" of "unix"
delimiter
str
","
Enkel teken dat velden scheidt β€” gebruik "\t" voor TSV-uitvoer
quotechar
str
"
Teken dat wordt gebruikt om velden met het scheidingsteken te quoten
quoting
int
csv.QUOTE_MINIMAL
Bepaalt wanneer quoting wordt toegepast β€” MINIMAL, ALL, NONNUMERIC, NONE
lineterminator
str
"\r\n"
Tekenreeks die na elke rij wordt toegevoegd β€” overschrijf naar "\n" voor Unix-stijl uitvoer

pandas β€” JSON naar CSV converteren met DataFrames

Als u al werkt in een pandas-intensieve codebase, of als uw JSON geneste objecten heeft die u moet afvlakken, vereist de pandas-aanpak aanzienlijk minder code dan de stdlib-versie. De afweging: pandas is een afhankelijkheid van ~30 MB. Voor een wegwerpscript is dat prima. Voor een Docker-image die u naar productie stuurt, houdt de stdlib-aanpak het lichter.

Python 3.8+ β€” pandas read_json en daarna to_csv
import pandas as pd

# Lees JSON-array direct in een DataFrame
df = pd.read_json("warehouse_inventory.json")

# Schrijf naar CSV β€” index=False voorkomt de automatisch gegenereerde rijnummers
df.to_csv("warehouse_inventory.csv", index=False)

# Dat is alles. Twee regels. pandas leidt kolomtypes automatisch af.

De index=False vlag is een van die dingen die u elke keer opzoekt. Zonder dit schrijft pandas een 0, 1, 2, ... kolom als de eerste kolom van uw CSV. Niemand wil dat.

Geneste JSON afvlakken met json_normalize

Echte API-antwoorden zijn zelden plat. Bestellingen bevatten verzendadressen, gebruikers bevatten geneste voorkeuren, telemetriegebeurtenissen bevatten geneste metadata. pd.json_normalize() loopt door geneste dictionaries en vlakt ze af naar kolommen met punt-gescheiden namen.

Python 3.8+ β€” geneste JSON afvlakken met json_normalize
import json
import pandas as pd

api_response = """
[
  {
    "order_id": "ord_91a3",
    "placed_at": "2026-03-15T09:30:00Z",
    "customer": {
      "name": "Sarah Chen",
      "email": "s.chen@example.com",
      "tier": "premium"
    },
    "shipping": {
      "method": "express",
      "address": {
        "city": "Portland",
        "state": "OR",
        "zip": "97201"
      }
    },
    "total": 299.95
  },
  {
    "order_id": "ord_b7f2",
    "placed_at": "2026-03-15T14:12:00Z",
    "customer": {
      "name": "James Park",
      "email": "j.park@example.com",
      "tier": "standard"
    },
    "shipping": {
      "method": "standard",
      "address": {
        "city": "Austin",
        "state": "TX",
        "zip": "73301"
      }
    },
    "total": 87.50
  }
]
"""

orders = json.loads(api_response)

# json_normalize vlakt geneste dicts af β€” sep bepaalt het scheidingsteken
df = pd.json_normalize(orders, sep="_")
df.to_csv("flat_orders.csv", index=False)

# Resulterende kolommen:
# order_id, placed_at, customer_name, customer_email, customer_tier,
# shipping_method, shipping_address_city, shipping_address_state,
# shipping_address_zip, total

De sep="_" parameter bepaalt hoe geneste sleutelnamen worden samengevoegd. De standaard is ".", wat kolommen oplevert zoals customer.name. Ik geef de voorkeur aan underscores omdat punten in kolomnamen problemen geven bij SQL-imports en sommige spreadsheetformules.

Voor API-antwoorden die de recordsarray onder een geneste sleutel verpakken, gebruik de record_path parameter. Als het antwoord er zo uitziet {"data": {"orders": [...]}}, geef dan record_path=["data", "orders"] door om naar de juiste lijst te navigeren. De optionele meta parameter laat u velden op het bovenste niveau naast de geneste records ophalen β€” handig wanneer het antwoord paginatie-informatie op het hoogste niveau bevat (paginanummer, totaal aantal) die u als kolom in elke rij wilt hebben. Samen verwerken record_path en meta de meeste gangbare geneste API-antwoordvormen zonder aangepaste voorbewerking.

DataFrame.to_csv() Parameters Referentie

DataFrame.to_csv() heeft meer dan 20 parameters. Dit zijn de relevante voor JSON-naar-CSV workflows.

Parameter
Type
Standaard
Beschrijving
path_or_buf
str / Path / None
None
Bestandspad of buffer β€” None geeft CSV terug als string
sep
str
","
Veldscheidingsteken β€” gebruik "\t" voor TSV
index
bool
True
Schrijf de rij-index als eerste kolom β€” zet dit bijna altijd op False
columns
list
None
Selecteer en herorden kolommen in de uitvoer
header
bool / list
True
Schrijf kolomnamen β€” zet False bij toevoegen aan een bestaand bestand
encoding
str
"utf-8"
Uitvoercodering β€” gebruik "utf-8-sig" voor Excel-compatibiliteit op Windows
na_rep
str
""
Tekenreeksrepresentatie voor ontbrekende waarden (NaN, None)
quoting
int
csv.QUOTE_MINIMAL
Bepaalt wanneer velden worden gequote
Python 3.8+ β€” to_csv met veelgebruikte parameter-overschrijvingen
import pandas as pd

df = pd.read_json("telemetry_events.json")

# TSV-uitvoer met expliciete codering en verwerking van ontbrekende waarden
df.to_csv(
    "telemetry_events.tsv",
    sep="\t",
    index=False,
    encoding="utf-8",
    na_rep="NULL",
    columns=["event_id", "timestamp", "source", "severity", "message"],
)

# Schrijven naar stdout voor gebruik in shellscripts
print(df.to_csv(index=False))

# Teruggeven als string (geen bestand geschreven)
csv_string = df.to_csv(index=False)
print(len(csv_string), "characters")

JSON naar CSV converteren vanuit een bestand en API-antwoord

De twee meest voorkomende praktijkscenario's: JSON lezen uit een bestand op schijf en converteren, of JSON ophalen van een HTTP API en het resultaat opslaan als CSV. In ontwikkeling kunt u wegkomen zonder foutafhandeling. In productie wordt die keuze een melding om 2 uur 's nachts. Bestanden bestaan misschien niet, API's kunnen 4xx- of 5xx-statuscodes teruggeven in plaats van JSON, de antwoordtekst kan een foutobject zijn in plaats van een array, of de JSON kan worden afgekapt door een netwerktimeout. De onderstaande patronen verwerken al deze gevallen expliciet, loggen fouten naar stderr en geven een rij-aantal terug zodat aanroepers nul-rij-uitvoeren kunnen detecteren en dienovereenkomstig kunnen alarmeren.

Bestand op schijf β€” lezen, converteren, opslaan

Python 3.8+ β€” JSON-bestand naar CSV converteren met foutafhandeling
import json
import csv
import sys

def json_file_to_csv(input_path: str, output_path: str) -> int:
    """Converteer een JSON-bestand met een array van objecten naar CSV.
    Geeft het aantal geschreven rijen terug.
    """
    try:
        with open(input_path, encoding="utf-8") as jf:
            data = json.load(jf)
    except FileNotFoundError:
        print(f"Fout: {input_path} niet gevonden", file=sys.stderr)
        return 0
    except json.JSONDecodeError as exc:
        print(f"Fout: ongeldige JSON in {input_path}: {exc.msg} op regel {exc.lineno}", file=sys.stderr)
        return 0

    if not isinstance(data, list) or not data:
        print(f"Fout: verwacht een niet-lege JSON-array in {input_path}", file=sys.stderr)
        return 0

    # Verzamel alle unieke sleutels over alle records β€” verwerkt inconsistente schema's
    all_keys: list[str] = []
    seen: set[str] = set()
    for record in data:
        for key in record:
            if key not in seen:
                all_keys.append(key)
                seen.add(key)

    with open(output_path, "w", newline="", encoding="utf-8") as cf:
        writer = csv.DictWriter(cf, fieldnames=all_keys, restval="", extrasaction="ignore")
        writer.writeheader()
        writer.writerows(data)

    return len(data)

rows = json_file_to_csv("deploy_logs.json", "deploy_logs.csv")
print(f"Schreef {rows} rijen naar deploy_logs.csv")

HTTP API-antwoord β€” ophalen en converteren

Python 3.8+ β€” JSON ophalen van API en opslaan als CSV
import json
import csv
import urllib.request
import urllib.error

def api_response_to_csv(url: str, output_path: str) -> int:
    """Haal JSON op van een REST API-eindpunt en schrijf het als CSV."""
    try:
        req = urllib.request.Request(url, headers={"Accept": "application/json"})
        with urllib.request.urlopen(req, timeout=30) as resp:
            if resp.status != 200:
                print(f"Fout: API gaf status {resp.status} terug")
                return 0
            body = resp.read().decode("utf-8")
    except urllib.error.URLError as exc:
        print(f"Fout: kon {url} niet bereiken: {exc.reason}")
        return 0

    try:
        records = json.loads(body)
    except json.JSONDecodeError as exc:
        print(f"Fout: API gaf ongeldige JSON terug: {exc.msg}")
        return 0

    if not isinstance(records, list) or not records:
        print("Fout: verwacht een niet-lege JSON-array van de API")
        return 0

    with open(output_path, "w", newline="", encoding="utf-8") as cf:
        writer = csv.DictWriter(cf, fieldnames=records[0].keys())
        writer.writeheader()
        writer.writerows(records)

    return len(records)

rows = api_response_to_csv(
    "https://api.internal.example.com/v2/deployments?status=completed",
    "completed_deployments.csv",
)
print(f"Exporteerde {rows} deployments naar CSV")
Opmerking:Het bovenstaande voorbeeld gebruikt urllib uit de standaardbibliotheek om het script vrij van afhankelijkheden te houden. Als u requests hebt geΓ―nstalleerd, vervang dan het urllib-gedeelte door resp = requests.get(url, timeout=30); records = resp.json() β€” de rest van de CSV-schrijfcode blijft identiek.

JSON naar CSV-conversie via de opdrachtregel

Soms heeft u gewoon een one-liner in de terminal nodig. Python's -c vlag laat u een snelle conversie uitvoeren zonder een scriptbestand aan te maken. Voor complexere transformaties, stuur eerst door jq om de data te hervormen en converteer daarna.

bash β€” one-liner json naar csv-conversie
# Python one-liner: leest JSON van stdin, schrijft CSV naar stdout
cat orders.json | python3 -c "
import json, csv, sys
data = json.load(sys.stdin)
w = csv.DictWriter(sys.stdout, fieldnames=data[0].keys())
w.writeheader()
w.writerows(data)
"

# Uitvoer opslaan naar een bestand
cat orders.json | python3 -c "
import json, csv, sys
data = json.load(sys.stdin)
w = csv.DictWriter(sys.stdout, fieldnames=data[0].keys())
w.writeheader()
w.writerows(data)
" > orders.csv
bash β€” zelfstandig CLI-script met argparse
# Sla op als json2csv.py en voer uit: python3 json2csv.py input.json -o output.csv
python3 -c "
import json, csv, argparse, sys

parser = argparse.ArgumentParser(description='Converteer JSON-array naar CSV')
parser.add_argument('input', help='Pad naar JSON-bestand')
parser.add_argument('-o', '--output', default=None, help='Uitvoer CSV-pad (standaard: stdout)')
parser.add_argument('-d', '--delimiter', default=',', help='CSV-scheidingsteken')
args = parser.parse_args()

with open(args.input) as f:
    data = json.load(f)

out = open(args.output, 'w', newline='') if args.output else sys.stdout
writer = csv.DictWriter(out, fieldnames=data[0].keys(), delimiter=args.delimiter)
writer.writeheader()
writer.writerows(data)
if args.output:
    out.close()
    print(f'Schreef {len(data)} rijen naar {args.output}', file=sys.stderr)
" "$@"
bash β€” jq + csvkit gebruiken voor complexe transformaties
# Installeer csvkit: pip install csvkit

# jq vlakt af en selecteert velden, in2csv verzorgt de CSV-opmaak
cat api_response.json | jq '[.[] | {id: .order_id, customer: .customer.name, total}]' | in2csv -f json > orders.csv

# Miller (mlr) is een andere optie voor JSON-naar-CSV
mlr --json2csv cat orders.json > orders.csv

Miller (mlr) is een zelfstandig binair bestand dat JSON, CSV en TSV behandelt als eersteklas formaten zonder Python runtime. De --json2csv vlag converteert JSON-invoer naar CSV in één doorgang, en u kunt Miller-werkwoorden koppelen om kolommen te filteren, sorteren of hernoemen in dezelfde opdracht voor het schrijven van uitvoer. Installeer via Homebrew op macOS (brew install miller) of uw Linux-pakketbeheerder. Het is bijzonder nuttig in CI-pipelines waar u snelle JSON-naar-CSV-conversie wilt zonder een Python-omgeving op te starten.

Krachtig alternatief β€” pandas met pyarrow

Voor datasets in de tientallen miljoenen rijen leest en schrijft pandas met de pyarrow backend aanzienlijk sneller dan de standaard. De C-gebaseerde Arrow-engine verwerkt kolomgegevens efficiΓ«nter dan de rij-voor-rij csv-module van Python. De API blijft hetzelfde β€” u stelt alleen de engine-parameter in.

bash β€” pyarrow installeren
pip install pyarrow
Python 3.8+ β€” pandas met pyarrow voor sneller CSV-schrijven
import pandas as pd

# Lees JSON met pyarrow-engine (sneller parsen voor grote bestanden)
df = pd.read_json("sensor_readings.json", engine="pyarrow")

# to_csv heeft geen engine-parameter, maar de DataFrame-bewerkingen
# tussen lezen en schrijven profiteren van de kolomindeling van pyarrow
df.to_csv("sensor_readings.csv", index=False)

# Voor echt grote exports, overweeg schrijven naar Parquet in plaats van CSV
# β€” binair formaat, 5-10x kleiner, behoudt types
df.to_parquet("sensor_readings.parquet", engine="pyarrow")

Als u meer dan een paar honderd MB JSON verwerkt en de uiteindelijke afnemer Parquet accepteert, sla dan CSV volledig over. Parquet is kleiner, behoudt kolomtypes, en zowel Redshift als BigQuery laden het native. CSV is een lossy formaat β€” elke waarde wordt een string.

Terminaluitvoer met syntaxismarkering

De rich bibliotheek geeft tabellen weer met randen, uitlijning en kleur in de terminal β€” handig voor het bekijken van een conversie tijdens ontwikkeling zonder het uitvoerbestand te openen.

bash β€” rich installeren
pip install rich
Python 3.8+ β€” CSV-uitvoer bekijken in terminal met rich
import json
from rich.console import Console
from rich.table import Table

json_string = """
[
  {"hostname": "web-prod-1", "cpu_percent": 72.3, "memory_mb": 3840, "uptime_hours": 720},
  {"hostname": "web-prod-2", "cpu_percent": 45.1, "memory_mb": 2560, "uptime_hours": 168},
  {"hostname": "db-replica-1", "cpu_percent": 91.7, "memory_mb": 7680, "uptime_hours": 2160}
]
"""

records = json.loads(json_string)
console = Console()

table = Table(title="Servermetrics Preview", show_lines=True)
for key in records[0]:
    table.add_column(key, style="cyan" if key == "hostname" else "white")

for row in records:
    table.add_row(*[str(v) for v in row.values()])

console.print(table)
# Geeft een kleurgemarkeerde tabel met randen weer in de terminal
Waarschuwing:Rich is uitsluitend voor terminalweergave. Gebruik het niet om CSV-bestanden te genereren β€” het voegt ANSI-escapecodes toe die de uitvoer beschadigen. Schrijf naar bestanden met csv.DictWriter of DataFrame.to_csv(), en gebruik rich alleen voor het bekijken.

Werken met grote JSON-bestanden

json.load() leest het volledige bestand in het geheugen. Voor een JSON-bestand van 200 MB betekent dat ~200 MB aan ruwe tekst plus de Python-object-overhead β€” gemakkelijk 500 MB+ aan heap-gebruik. Voor bestanden boven 100 MB, stream de invoer met ijson en schrijf CSV-rijen terwijl u bezig bent.

bash β€” ijson installeren
pip install ijson

JSON-array naar CSV streamen met ijson

Python 3.8+ β€” grote JSON-array naar CSV streamen met constant geheugen
import ijson
import csv

def stream_json_to_csv(json_path: str, csv_path: str) -> int:
    """Converteer een grote JSON-array naar CSV zonder alles in het geheugen te laden."""
    with open(json_path, "rb") as jf, open(csv_path, "w", newline="", encoding="utf-8") as cf:
        # ijson.items levert elk element van de bovenste array één voor één op
        records = ijson.items(jf, "item")

        first_record = next(records)
        fieldnames = list(first_record.keys())

        writer = csv.DictWriter(cf, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerow(first_record)

        count = 1
        for record in records:
            writer.writerow(record)
            count += 1

    return count

rows = stream_json_to_csv("clickstream_2026_03.json", "clickstream_2026_03.csv")
print(f"Streamde {rows} records naar CSV")

NDJSON / JSON Lines β€” één object per regel

NDJSON (Newline-Delimited JSON), ook wel JSON Lines of .jsonl genoemd, slaat één geldig JSON-object per regel op zonder omhullende array. Dit formaat komt veel voor in logpipelines, eventstreams (Kafka, Kinesis) en bulkexports van diensten zoals Elasticsearch en BigQuery. Omdat elke regel een zelfstandig JSON-object is, kunt u een NDJSON-bestand verwerken met een gewone Python for lus over de bestandshandler β€” geen ijson-bibliotheek nodig. Het geheugen blijft constant ongeacht de bestandsgrootte, waardoor dit de eenvoudigste streaming-aanpak is wanneer uw brongegevens al in JSON Lines-formaat zijn.

Python 3.8+ β€” NDJSON naar CSV converteren regel voor regel
import json
import csv

def ndjson_to_csv(ndjson_path: str, csv_path: str) -> int:
    """Converteer een newline-delimited JSON-bestand naar CSV, één regel tegelijk."""
    with open(ndjson_path, encoding="utf-8") as nf:
        first_line = nf.readline()
        first_record = json.loads(first_line)
        fieldnames = list(first_record.keys())

        with open(csv_path, "w", newline="", encoding="utf-8") as cf:
            writer = csv.DictWriter(cf, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerow(first_record)

            count = 1
            for line in nf:
                line = line.strip()
                if not line:
                    continue
                try:
                    record = json.loads(line)
                    writer.writerow(record)
                    count += 1
                except json.JSONDecodeError:
                    continue  # sla misvormde regels over

    return count

rows = ndjson_to_csv("access_log.ndjson", "access_log.csv")
print(f"Converteerde {rows} logvermeldingen naar CSV")
Opmerking:Schakel over naar streaming wanneer het JSON-bestand groter is dan 100 MB. Een JSON-array van 1 GB geladen met json.load() kan 3-5 GB RAM verbruiken door de Python-object-overhead. Met ijson blijft het geheugen constant ongeacht de bestandsgrootte. Als u gewoon een snel conversie van een klein bestand nodig heeft, plak het dan in de JSON naar CSV converter in plaats daarvan.

Veelgemaakte fouten

❌ Ontbrekende newline='' in open() β€” lege rijen op Windows

Probleem: De csv-module schrijft \r\n-regelafsluitingen. Zonder newline='' voegt Python's tekstmodus op Windows nog een \r toe, wat dubbelspatiΓ«erde uitvoer oplevert.

Oplossing: Geef altijd newline='' door bij het openen van een bestand voor CSV-schrijven. Het is onschadelijk op macOS/Linux.

Before Β· Python
After Β· Python
with open("output.csv", "w") as f:
    writer = csv.DictWriter(f, fieldnames=columns)
    writer.writeheader()
    writer.writerows(data)
# Lege rijen tussen elke datarij op Windows
with open("output.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=columns)
    writer.writeheader()
    writer.writerows(data)
# Schone uitvoer op alle platforms
❌ index=False vergeten in pandas to_csv()

Probleem: Zonder index=False voegt pandas een automatisch oplopende rijnummerkolom (0, 1, 2, ...) toe die de CSV vervuilt met gegevens die nooit in de oorspronkelijke JSON stonden.

Oplossing: Geef index=False door aan to_csv(). Als u daadwerkelijk een indexkolom nodig heeft, geef deze expliciet een naam met df.index.name = 'row_num'.

Before Β· Python
After Β· Python
df = pd.read_json("events.json")
df.to_csv("events.csv")
# CSV krijgt een extra naamloze kolom: ,event_id,timestamp,...
# De beginkomma breekt veel CSV-parsers
df = pd.read_json("events.json")
df.to_csv("events.csv", index=False)
# Schone CSV: event_id,timestamp,...
❌ records[0].keys() gebruiken bij records met inconsistente sleutels

Probleem: Als JSON-objecten verschillende sleutels hebben (sommige records hebben optionele velden), slaat het gebruik van de sleutels van het eerste record als fieldnames stilzwijgend kolommen over die alleen in latere records voorkomen.

Oplossing: Verzamel alle unieke sleutels over alle records voordat u de DictWriter aanmaakt.

Before Β· Python
After Β· Python
records = json.load(f)
writer = csv.DictWriter(out, fieldnames=records[0].keys())
# Mist het veld "discount" dat alleen in records[2] voorkomt
records = json.load(f)
all_keys = list(dict.fromkeys(k for r in records for k in r))
writer = csv.DictWriter(out, fieldnames=all_keys, restval="")
# Elke sleutel van elk record is opgenomen als kolom
❌ Geneste dicts direct naar CSV schrijven zonder afvlakken

Probleem: csv.DictWriter roept str() aan op geneste dicts, wat kolommen oplevert met waarden zoals "{'city': 'Portland'}"β€” ruwe Python-representatie, geen echte data.

Oplossing: Vlak geneste objecten eerst af met pd.json_normalize() of een aangepaste afvlakkingsfunctie.

Before Β· Python
After Β· Python
records = [{"id": "evt_1", "meta": {"source": "web", "region": "us-west"}}]
writer = csv.DictWriter(f, fieldnames=["id", "meta"])
writer.writerows(records)
# meta-kolom bevat: {'source': 'web', 'region': 'us-west'}
import pandas as pd
records = [{"id": "evt_1", "meta": {"source": "web", "region": "us-west"}}]
df = pd.json_normalize(records, sep="_")
df.to_csv("events.csv", index=False)
# Kolommen: id, meta_source, meta_region

csv.DictWriter vs pandas β€” Snelle vergelijking

Methode
Geneste JSON
Aangepaste types
Streaming
Afhankelijkheden
Installatie vereist
csv.DictWriter
βœ— (handmatig afvlakken)
βœ—
βœ“ (rij voor rij)
Geen
Nee (stdlib)
csv.writer
βœ—
βœ—
βœ“ (rij voor rij)
Geen
Nee (stdlib)
pd.DataFrame.to_csv()
βœ— (alleen plat)
βœ“ (via dtypes)
βœ—
pandas + numpy
pip install
pd.json_normalize() + to_csv()
βœ“
βœ“ (via dtypes)
βœ—
pandas + numpy
pip install
csv.writer + json_flatten
βœ“
βœ—
βœ“
flatten_json
pip install
jq + csvkit (CLI)
βœ“ (via jq)
N/A
βœ“
jq, csvkit
Systeeminstallatie

Gebruik csv.DictWriter wanneer u geen afhankelijkheden nodig heeft, uw JSON plat is, en het script draait in een beperkte omgeving (CI-containers, Lambda-functies, ingebedde Python). Gebruik pd.json_normalize() + to_csv() wanneer de JSON genest is, u data moet transformeren of filteren voor de export, of u al in een pandas-workflow werkt. Voor bestanden die niet in het geheugen passen, combineer ijson met csv.DictWriter voor constant-geheugen streaming.

Voor snelle conversies zonder code verwerkt de JSON naar CSV converter op ToolDeck het zonder enige Python-installatie.

Veelgestelde vragen

Hoe converteer ik JSON naar CSV in Python zonder pandas?

Gebruik de ingebouwde json- en csv-modules. Roep json.load() aan om het JSON-bestand te parsen naar een lijst met dicts, haal fieldnames op uit de sleutels van de eerste dict, maak een csv.DictWriter aan, roep writeheader() aan en daarna writerows(). Deze aanpak heeft geen externe afhankelijkheden en werkt in elke Python 3.x-omgeving. Hij draait ook sneller dan pandas voor kleine bestanden, omdat er geen DataFrame-allocatie plaatsvindt. Als uw JSON-objecten inconsistente sleutels hebben over records heen, verzamel dan eerst alle unieke sleutels met dict.fromkeys(k for r in records for k in r) voordat u ze als fieldnames doorgeeft om ontbrekende kolommen te vermijden.

Python
import json
import csv

with open("orders.json") as f:
    records = json.load(f)

with open("orders.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=records[0].keys())
    writer.writeheader()
    writer.writerows(records)

Hoe ga ik om met geneste JSON bij het converteren naar CSV?

Platte JSON-arrays worden direct omgezet naar CSV-rijen, maar geneste objecten moeten eerst worden afgevlakt. Met pandas doet pd.json_normalize() dit automatisch β€” het verbindt geneste sleutels met een punt als scheidingsteken (bijv. "address.city"). Zonder pandas schrijft u een recursieve functie die door de dict loopt en sleutels samenvoegt met een scheidingsteken. Voor diep geneste structuren met meerdere niveaus verwerkt json_normalize ze allemaal in één stap. De sep-parameter bepaalt het verbindingsteken tussen sleutelsegmenten β€” een underscore is doorgaans veiliger dan de standaard punt voor SQL-imports en compatibiliteit met spreadsheetformules.

Python
import pandas as pd

nested_data = [
    {"id": "ord_91a3", "customer": {"name": "Anna de Vries", "email": "a.devries@voorbeeld.nl"}},
]
df = pd.json_normalize(nested_data, sep="_")
# Kolommen: id, customer_name, customer_email
df.to_csv("flat_orders.csv", index=False)

Waarom heeft mijn CSV lege rijen tussen de datarijen op Windows?

De csv-module schrijft standaard \r\n-regelafsluitingen. Op Windows voegt het openen van het bestand in tekstmodus nog een extra \r toe, wat resulteert in \r\r\n β€” dat verschijnt als een lege rij. De oplossing is om altijd newline="" door te geven aan open(). Dit vertelt Python om regelafsluitingen niet te vertalen en laat de csv-module ze afhandelen. Dit patroon is vereist ongeacht het besturingssysteem β€” het is onschadelijk op macOS en Linux, maar cruciaal op Windows. De Python-documentatie noemt dit expliciet in de sectie van de csv-module als de juiste manier om bestanden te openen voor CSV-schrijven.

Python
# Fout β€” lege rijen op Windows
with open("output.csv", "w") as f:
    writer = csv.writer(f)

# Correct β€” newline="" voorkomt dubbele \r
with open("output.csv", "w", newline="") as f:
    writer = csv.writer(f)

Hoe voeg ik JSON-records toe aan een bestaand CSV-bestand?

Open het bestand in toevoegmodus ("a") en maak een DictWriter aan met dezelfde fieldnames. Sla writeheader() over omdat de headerrij al bestaat. Met pandas gebruikt u to_csv(mode="a", header=False). Zorg ervoor dat de kolomvolgorde overeenkomt met het bestaande bestand, anders komen de gegevens in de verkeerde kolommen terecht. Als u niet zeker bent over de kolomvolgorde in het bestaande bestand, open het dan eerst met csv.DictReader en lees de fieldnames uit het fieldnames-attribuut voordat u de writer aanmaakt voor het toevoegen.

Python
import csv

new_records = [
    {"order_id": "ord_f4c1", "total": 89.50, "status": "shipped"},
]

with open("orders.csv", "a", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["order_id", "total", "status"])
    writer.writerows(new_records)

Wat is de snelste manier om een groot JSON-bestand naar CSV te converteren in Python?

Voor bestanden onder 500 MB is pd.read_json() gevolgd door to_csv() de snelste enkelvoudige aanroep β€” pandas gebruikt intern geoptimaliseerde C-code. Voor bestanden boven 500 MB gebruikt u ijson om JSON-records te streamen en schrijft u ze rij voor rij naar CSV met csv.DictWriter. Dit houdt het geheugengebruik constant ongeacht de bestandsgrootte. Voor NDJSON-bestanden (één JSON-object per regel) heeft u helemaal geen ijson nodig β€” een gewone Python for-lus over de bestandshandler verwerkt elke regel onafhankelijk en bereikt constant geheugen zonder externe bibliotheek.

Python
# Snel voor bestanden die in het geheugen passen
import pandas as pd
df = pd.read_json("large_dataset.json")
df.to_csv("large_dataset.csv", index=False)

# Streaming voor bestanden die niet in het geheugen passen
import ijson, csv
with open("huge.json", "rb") as jf, open("huge.csv", "w", newline="") as cf:
    records = ijson.items(jf, "item")
    first = next(records)
    writer = csv.DictWriter(cf, fieldnames=first.keys())
    writer.writeheader()
    writer.writerow(first)
    for record in records:
        writer.writerow(record)

Kan ik CSV-uitvoer naar stdout schrijven in plaats van naar een bestand in Python?

Ja. Geef sys.stdout door als het file-object aan csv.writer() of csv.DictWriter(). Dit is handig voor het doorsluizen van uitvoer in shellscripts of voor snel debuggen. Met pandas roept u to_csv(sys.stdout, index=False) aan, of to_csv(None) om een string te krijgen die u kunt printen. Geen tijdelijk bestand nodig. Bij het schrijven naar stdout op Windows roept u eerst sys.stdout.reconfigure(newline="") aan om het dubbele regelteruglooprobleem te vermijden, omdat stdout standaard in tekstmodus opent.

Python
import csv
import sys
import json

data = json.loads('[{"host":"web-1","cpu":72.3},{"host":"web-2","cpu":45.1}]')
writer = csv.DictWriter(sys.stdout, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
# host,cpu
# web-1,72.3
# web-2,45.1

Gerelateerde tools

MS
Maria SantosBackend Developer

Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.

PS
Priya SharmaTechnisch beoordelaar

Priya is a data scientist and machine learning engineer who has worked across the full Python data stack β€” from raw data ingestion and cleaning to model deployment and monitoring. She is passionate about reproducible research, Jupyter-based workflows, and the practical engineering side of ML. She writes about NumPy, Pandas, data serialisation, and the Python patterns that make data pipelines reliable at scale.