Skip to content

Commit e527545

Browse files
author
Albert Villanova del Moral
committed
BUG: Fix type coercion in read_json orient='table' (pandas-dev#21345)
1 parent 5278cc6 commit e527545

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

pandas/io/json/json.py

+27-5
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ def _write(self, obj, orient, double_precision, ensure_ascii,
226226
return serialized
227227

228228

229-
def read_json(path_or_buf=None, orient=None, typ='frame', dtype=True,
229+
def read_json(path_or_buf=None, orient=None, typ='frame', dtype=None,
230230
convert_axes=True, convert_dates=True, keep_default_dates=True,
231231
numpy=False, precise_float=False, date_unit=None, encoding=None,
232232
lines=False, chunksize=None, compression='infer'):
@@ -277,9 +277,24 @@ def read_json(path_or_buf=None, orient=None, typ='frame', dtype=True,
277277
'table' as an allowed value for the ``orient`` argument
278278
279279
typ : type of object to recover (series or frame), default 'frame'
280-
dtype : boolean or dict, default True
281-
If True, infer dtypes, if a dict of column to dtype, then use those,
280+
dtype : boolean or dict
281+
If True, infer dtypes; if a dict of column to dtype, then use those;
282282
if False, then don't infer dtypes at all, applies only to the data.
283+
284+
The allowed and default values depend on the value of the `orient`
285+
parameter:
286+
287+
- if ``orient != 'table'``:
288+
289+
- allowed ``dtype`` values are True, False or a dict
290+
- default is True
291+
292+
- if ``orient == 'table'``:
293+
294+
- allowed and default ``dtype`` is False
295+
296+
.. versionchanged:: 0.24.2 set default False for ``orient='table'``
297+
283298
convert_axes : boolean, default True
284299
Try to convert the axes to the proper dtypes.
285300
convert_dates : boolean, default True
@@ -408,6 +423,9 @@ def read_json(path_or_buf=None, orient=None, typ='frame', dtype=True,
408423
{"index": "row 2", "col 1": "c", "col 2": "d"}]}'
409424
"""
410425

426+
if dtype and orient == 'table':
427+
raise ValueError("'dtype' is only valid when 'orient' is not 'table'")
428+
411429
compression = _infer_compression(path_or_buf, compression)
412430
filepath_or_buffer, _, compression, should_close = get_filepath_or_buffer(
413431
path_or_buf, encoding=encoding, compression=compression,
@@ -600,15 +618,19 @@ class Parser(object):
600618
'us': long(31536000000000),
601619
'ns': long(31536000000000000)}
602620

603-
def __init__(self, json, orient, dtype=True, convert_axes=True,
621+
def __init__(self, json, orient, dtype=None, convert_axes=True,
604622
convert_dates=True, keep_default_dates=False, numpy=False,
605623
precise_float=False, date_unit=None):
606624
self.json = json
607625

608626
if orient is None:
609627
orient = self._default_orient
610-
611628
self.orient = orient
629+
630+
if orient == 'table':
631+
dtype = False
632+
if dtype is None:
633+
dtype = True
612634
self.dtype = dtype
613635

614636
if orient == "split":

pandas/tests/io/json/test_pandas.py

+6
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,12 @@ def test_data_frame_size_after_to_json(self):
12021202

12031203
assert size_before == size_after
12041204

1205+
def test_from_json_to_json_table_dtypes(self):
1206+
expected = pd.DataFrame({'a': [1, 2], 'b': [3., 4.], 'c': ['5', '6']})
1207+
dfjson = expected.to_json(orient='table')
1208+
result = pd.read_json(dfjson, orient='table')
1209+
assert_frame_equal(result, expected)
1210+
12051211
@pytest.mark.parametrize('data, expected', [
12061212
(DataFrame([[1, 2], [4, 5]], columns=['a', 'b']),
12071213
{'columns': ['a', 'b'], 'data': [[1, 2], [4, 5]]}),

0 commit comments

Comments
 (0)