Use DataFrame.to_json() and choose an orient that matches the JSON shape your application expects. For a common array of row objects, use df.to_json(orient="records"). The method returns a JSON string unless you give it a path or writable file-like object.
Choose the JSON structure
The orient argument determines what the output represents and whether it retains labels. The pandas default is columns; set the orientation explicitly when another application expects a particular format. See the pandas DataFrame.to_json API reference.
| Orientation | Output shape | When to use it |
|---|---|---|
records |
A list of objects, one per row | Useful for API payloads and JSON Lines. Index labels are omitted. |
split |
An object with index, columns, and data arrays |
Use when you want row and column labels represented separately. |
index |
An object mapping each index label to a row object | Use when row labels should be keys. The index must be unique for the corresponding reader orientation. |
columns |
An object mapping each column to index/value mappings | Column-oriented output and the documented default. |
values |
An array of row arrays | Use when values matter but labels do not. |
table |
An object containing schema and data |
Use when table-schema metadata is useful; check the index-name round-trip caveats below. |
Make a row-object array
For example, given a DataFrame with columns name and score, records orientation produces a list of objects keyed by those column names:
json_text = df.to_json(orient="records")
This shape does not include the DataFrame index. If an index value is meaningful to the recipient, include it as a regular column before serialization or choose an orientation that represents index labels.
#1 Best Overall
Control dates, missing values, and numbers
By default, pandas converts datetime values to Unix timestamps. The default date format is epoch for most orientations and iso for table; epoch date formatting is deprecated since pandas 3.0.0, and the documentation directs users to ISO formatting. If the receiving application needs readable dates, specify the format rather than relying on the default:
json_text = df.to_json(orient="records", date_format="iso")
date_unit sets timestamp or ISO precision. Its accepted values are s (seconds), ms (milliseconds), us (microseconds), and ns (nanoseconds); the documented default is milliseconds. pandas converts NaN and None to JSON null.
Rank #2
For floating-point output, double_precision controls the number of decimal places and supports a documented maximum of 15. force_ascii controls whether non-ASCII characters are escaped. JSON serialization should not be treated as a lossless record of every pandas dtype: the JSON representation and the types inferred when it is read back may differ.
Write JSON to a file or as JSON Lines
Pass a path or a file-like object with a write() method to path_or_buf to write output instead of receiving a string. For a JSON Lines file, use records orientation with lines=True:
df.to_json("output.jsonl", orient="records", lines=True)
Each line is a JSON record, rather than the entire DataFrame encoded as one JSON array. The pandas API permits lines=True only with orient="records". Append mode is supported only when both records orientation and lines=True are used. Compression can be inferred from recognized filename extensions or set with the compression argument.
Read the JSON back into pandas
Use the matching orientation when loading a JSON string. Wrap the string in StringIO so read_json treats it as in-memory data:
import pandas as pd
from io import StringIO
json_text = df.to_json(orient="split")
restored = pd.read_json(StringIO(json_text), orient="split")
For JSON Lines, read with records orientation and lines=True:
restored = pd.read_json("output.jsonl", orient="records", lines=True)
The pandas read_json API reference documents constraints that can affect whether a chosen orientation is readable: index and columns orientations require a unique DataFrame index, while index, columns, and records require unique columns. For chunked reading of line-delimited JSON, read_json supports chunksize.
Best Value
If exact schema or index-name round-tripping matters with orient="table", check the documented edge cases: a literal index name of index is read back as None, and related caveats apply to certain MultiIndex names.
Quick Recap
Pick an orientation for your use case
- Choose
recordsfor a list of row objects; account for the fact that index labels are not included. - Choose
splitortablewhen labels or schema information matter, and verify index and column-name behavior if you need a precise round trip. - Choose
valuesonly when unlabeled row values are sufficient. - For JSON Lines, pair
orient="records"withlines=Truewhen writing and reading. - Set date formatting explicitly if the downstream consumer depends on a stable representation, and check inferred dtypes after loading when dtype fidelity matters.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




