From d8dc8eeae404012291e6b52b561385a33c0810e8 Mon Sep 17 00:00:00 2001 From: Kieran O'Mahony Date: Sat, 20 Jul 2013 09:34:20 +1000 Subject: [PATCH] ENH: expose ujson precise_float argument on decode --- pandas/io/json.py | 49 ++++++++++++++++-------- pandas/io/tests/test_json/test_pandas.py | 10 +++++ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/pandas/io/json.py b/pandas/io/json.py index ce95c3394ce2c..c3e56a05f13b0 100644 --- a/pandas/io/json.py +++ b/pandas/io/json.py @@ -119,7 +119,8 @@ def _format_dates(self): self.obj[c] = self._format_to_date(self.obj[c]) def read_json(path_or_buf=None, orient=None, typ='frame', dtype=True, - convert_axes=True, convert_dates=True, keep_default_dates=True, numpy=False): + convert_axes=True, convert_dates=True, keep_default_dates=True, + numpy=False, precise_float=False): """ Convert JSON string to pandas object @@ -187,7 +188,9 @@ def read_json(path_or_buf=None, orient=None, typ='frame', dtype=True, class Parser(object): - def __init__(self, json, orient, dtype=True, convert_axes=True, convert_dates=True, keep_default_dates=False, numpy=False): + def __init__(self, json, orient, dtype=True, convert_axes=True, + convert_dates=True, keep_default_dates=False, numpy=False, + precise_float=False): self.json = json if orient is None: @@ -200,6 +203,7 @@ def __init__(self, json, orient, dtype=True, convert_axes=True, convert_dates=Tr numpy = False self.numpy = numpy + self.precise_float = precise_float self.convert_axes = convert_axes self.convert_dates = convert_dates self.keep_default_dates = keep_default_dates @@ -347,24 +351,30 @@ def _parse_no_numpy(self): orient = self.orient if orient == "split": decoded = dict((str(k), v) - for k, v in loads(json).iteritems()) + for k, v in loads( + json, + precise_float=self.precise_float).iteritems()) self.obj = Series(dtype=None, **decoded) else: - self.obj = Series(loads(json), dtype=None) + self.obj = Series( + loads(json, precise_float=self.precise_float), dtype=None) def _parse_numpy(self): json = self.json orient = self.orient if orient == "split": - decoded = loads(json, dtype=None, numpy=True) + decoded = loads(json, dtype=None, numpy=True, + precise_float=self.precise_float) decoded = dict((str(k), v) for k, v in decoded.iteritems()) self.obj = Series(**decoded) elif orient == "columns" or orient == "index": self.obj = Series(*loads(json, dtype=None, numpy=True, - labelled=True)) + labelled=True, + precise_float=self.precise_float)) else: - self.obj = Series(loads(json, dtype=None, numpy=True)) + self.obj = Series(loads(json, dtype=None, numpy=True, + precise_float=self.precise_float)) def _try_convert_types(self): if self.obj is None: return @@ -381,18 +391,22 @@ def _parse_numpy(self): orient = self.orient if orient == "columns": - args = loads(json, dtype=None, numpy=True, labelled=True) + args = loads(json, dtype=None, numpy=True, labelled=True, + precise_float=self.precise_float) if args: args = (args[0].T, args[2], args[1]) self.obj = DataFrame(*args) elif orient == "split": - decoded = loads(json, dtype=None, numpy=True) + decoded = loads(json, dtype=None, numpy=True, + precise_float=self.precise_float) decoded = dict((str(k), v) for k, v in decoded.iteritems()) self.obj = DataFrame(**decoded) elif orient == "values": - self.obj = DataFrame(loads(json, dtype=None, numpy=True)) + self.obj = DataFrame(loads(json, dtype=None, numpy=True, + precise_float=self.precise_float)) else: - self.obj = DataFrame(*loads(json, dtype=None, numpy=True, labelled=True)) + self.obj = DataFrame(*loads(json, dtype=None, numpy=True, labelled=True, + precise_float=self.precise_float)) def _parse_no_numpy(self): @@ -400,15 +414,20 @@ def _parse_no_numpy(self): orient = self.orient if orient == "columns": - self.obj = DataFrame(loads(json), dtype=None) + self.obj = DataFrame( + loads(json, precise_float=self.precise_float), dtype=None) elif orient == "split": decoded = dict((str(k), v) - for k, v in loads(json).iteritems()) + for k, v in loads( + json, + precise_float=self.precise_float).iteritems()) self.obj = DataFrame(dtype=None, **decoded) elif orient == "index": - self.obj = DataFrame(loads(json), dtype=None).T + self.obj = DataFrame( + loads(json, precise_float=self.precise_float), dtype=None).T else: - self.obj = DataFrame(loads(json), dtype=None) + self.obj = DataFrame( + loads(json, precise_float=self.precise_float), dtype=None) def _try_convert_types(self): if self.obj is None: return diff --git a/pandas/io/tests/test_json/test_pandas.py b/pandas/io/tests/test_json/test_pandas.py index bc6ba1a45136c..dfa46189974f2 100644 --- a/pandas/io/tests/test_json/test_pandas.py +++ b/pandas/io/tests/test_json/test_pandas.py @@ -289,6 +289,16 @@ def test_series_to_json_except(self): s = Series([1, 2, 3]) self.assertRaises(ValueError, s.to_json, orient="garbage") + def test_series_from_json_precise_float(self): + s = Series([4.56, 4.56, 4.56]) + result = read_json(s.to_json(), typ='series', precise_float=True) + assert_series_equal(result, s) + + def test_frame_from_json_precise_float(self): + df = DataFrame([[4.56, 4.56, 4.56], [4.56, 4.56, 4.56]]) + result = read_json(df.to_json(), precise_float=True) + assert_frame_equal(result, df) + def test_typ(self): s = Series(range(6), index=['a','b','c','d','e','f'], dtype='int64')