Skip to content

Commit 8c8e73f

Browse files
committed
API/BUG: Make to_json index= consistent with orient
- split and table allow index=True/False - records and values only allow index=False - index and columns only allow index=True - raise for contradictions in the latter two - see pandas-dev#25513
1 parent 540db96 commit 8c8e73f

File tree

3 files changed

+41
-11
lines changed

3 files changed

+41
-11
lines changed

pandas/core/generic.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -2268,7 +2268,7 @@ def to_json(
22682268
default_handler: Callable[[Any], JSONSerializable] | None = None,
22692269
lines: bool_t = False,
22702270
compression: CompressionOptions = "infer",
2271-
index: bool_t = True,
2271+
index: bool_t | None = None,
22722272
indent: int | None = None,
22732273
storage_options: StorageOptions = None,
22742274
mode: Literal["a", "w"] = "w",
@@ -2337,10 +2337,17 @@ def to_json(
23372337
23382338
.. versionchanged:: 1.4.0 Zstandard support.
23392339
2340-
index : bool, default True
2341-
Whether to include the index values in the JSON string. Not
2342-
including the index (``index=False``) is only supported when
2343-
orient is 'split' or 'table'.
2340+
index : bool or None, default None
2341+
Whether to include the index values in the JSON string. Different
2342+
defaults and options depend on the 'orient' argument:
2343+
2344+
- 'split': default True, can also be False
2345+
- 'records': default False, cannot be True
2346+
- 'index': default True, cannot be False
2347+
- 'columns': default True, cannot be False
2348+
- 'values': default False, cannot be True
2349+
- 'table': default True, can also be False
2350+
23442351
indent : int, optional
23452352
Length of whitespace used to indent each record.
23462353

pandas/io/json/_json.py

+15-3
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,26 @@ def to_json(
140140
default_handler: Callable[[Any], JSONSerializable] | None = None,
141141
lines: bool = False,
142142
compression: CompressionOptions = "infer",
143-
index: bool = True,
143+
index: bool | None = None,
144144
indent: int = 0,
145145
storage_options: StorageOptions = None,
146146
mode: Literal["a", "w"] = "w",
147147
) -> str | None:
148-
if not index and orient not in ["split", "table"]:
148+
if index is None and orient in ["records", "values"]:
149+
index = False
150+
elif index is None:
151+
index = True
152+
153+
if not index and orient not in ["split", "table", "records", "values"]:
154+
raise ValueError(
155+
"'index=False' is only valid when 'orient' is 'split', 'table', " +\
156+
"'records', or 'values'"
157+
)
158+
159+
if index and orient in ["records", "values"]:
149160
raise ValueError(
150-
"'index=False' is only valid when 'orient' is 'split' or 'table'"
161+
"'index=True' is only valid when 'orient' is 'split', 'table', " +\
162+
"'index', or 'columns'. Convert index to column for other orients."
151163
)
152164

153165
if lines and orient != "records":

pandas/tests/io/json/test_pandas.py

+14-3
Original file line numberDiff line numberDiff line change
@@ -1476,17 +1476,28 @@ def test_index_false_to_json_table(self, data):
14761476

14771477
assert result == expected
14781478

1479-
@pytest.mark.parametrize("orient", ["records", "index", "columns", "values"])
1479+
@pytest.mark.parametrize("orient", ["index", "columns"])
14801480
def test_index_false_error_to_json(self, orient):
1481-
# GH 17394
1481+
# GH 17394, 25513
14821482
# Testing error message from to_json with index=False
14831483

14841484
df = DataFrame([[1, 2], [4, 5]], columns=["a", "b"])
14851485

1486-
msg = "'index=False' is only valid when 'orient' is 'split' or 'table'"
1486+
msg = "'index=False' is only valid when 'orient' is 'split', 'table', 'records', or 'values'"
14871487
with pytest.raises(ValueError, match=msg):
14881488
df.to_json(orient=orient, index=False)
14891489

1490+
@pytest.mark.parametrize("orient", ["records", "values"])
1491+
def test_index_true_error_to_json(self, orient):
1492+
# GH 25513
1493+
# Testing error message from to_json with index=True
1494+
1495+
df = DataFrame([[1, 2], [4, 5]], columns=["a", "b"])
1496+
1497+
msg = "'index=True' is only valid when 'orient' is 'split', 'table', 'index', or 'columns'"
1498+
with pytest.raises(ValueError, match=msg):
1499+
df.to_json(orient=orient, index=True)
1500+
14901501
@pytest.mark.parametrize("orient", ["split", "table"])
14911502
@pytest.mark.parametrize("index", [True, False])
14921503
def test_index_false_from_json_to_json(self, orient, index):

0 commit comments

Comments
 (0)