Skip to content

Commit 7cad1bb

Browse files
committed
Merge branch 'ujson-unique-keys' of https://github.com/Komnomnomnom/pandas into Komnomnomnom-ujson-unique-keys
2 parents e07dc19 + f735141 commit 7cad1bb

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

pandas/io/json.py

+16
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class SeriesWriter(Writer):
7878
_default_orient = 'index'
7979

8080
def _format_axes(self):
81+
if not self.obj.index.is_unique and self.orient == 'index':
82+
raise ValueError("Series index must be unique for orient="
83+
"'%s'" % self.orient)
8184
if self._needs_to_date(self.obj.index):
8285
self.copy_if_needed()
8386
self.obj.index = self._format_to_date(self.obj.index.to_series())
@@ -97,6 +100,15 @@ class FrameWriter(Writer):
97100

98101
def _format_axes(self):
99102
""" try to axes if they are datelike """
103+
if not self.obj.index.is_unique and self.orient in (
104+
'index', 'columns'):
105+
raise ValueError("DataFrame index must be unique for orient="
106+
"'%s'." % self.orient)
107+
if not self.obj.columns.is_unique and self.orient in (
108+
'index', 'columns', 'records'):
109+
raise ValueError("DataFrame columns must be unique for orient="
110+
"'%s'." % self.orient)
111+
100112
if self.orient == 'columns':
101113
axis = 'index'
102114
elif self.orient == 'index':
@@ -134,10 +146,14 @@ def read_json(path_or_buf=None, orient=None, typ='frame', dtype=True,
134146
Series :
135147
default is 'index'
136148
allowed values are: {'split','records','index'}
149+
The Series index must be unique for orient 'index'.
137150
138151
DataFrame :
139152
default is 'columns'
140153
allowed values are: {'split','records','index','columns','values'}
154+
The DataFrame index must be unique for orients 'index' and 'columns'.
155+
The DataFrame columns must be unique for orients 'index', 'columns',
156+
and 'records'.
141157
142158
The format of the JSON string
143159
split : dict like {index -> [index], columns -> [columns], data -> [values]}

pandas/io/tests/test_json/test_pandas.py

+39
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,34 @@ def setUp(self):
5454
self.tsframe = _tsframe.copy()
5555
self.mixed_frame = _mixed_frame.copy()
5656

57+
def test_frame_non_unique_index(self):
58+
df = DataFrame([['a', 'b'], ['c', 'd']], index=[1, 1],
59+
columns=['x', 'y'])
60+
61+
self.assertRaises(ValueError, df.to_json, orient='index')
62+
self.assertRaises(ValueError, df.to_json, orient='columns')
63+
64+
assert_frame_equal(
65+
df, read_json(df.to_json(orient='split'), orient='split'))
66+
unser = read_json(df.to_json(orient='records'), orient='records')
67+
self.assert_(df.columns.equals(unser.columns))
68+
np.testing.assert_equal(df.values, unser.values)
69+
unser = read_json(df.to_json(orient='values'), orient='values')
70+
np.testing.assert_equal(df.values, unser.values)
71+
72+
def test_frame_non_unique_columns(self):
73+
df = DataFrame([['a', 'b'], ['c', 'd']], index=[1, 2],
74+
columns=['x', 'x'])
75+
76+
self.assertRaises(ValueError, df.to_json, orient='index')
77+
self.assertRaises(ValueError, df.to_json, orient='columns')
78+
self.assertRaises(ValueError, df.to_json, orient='records')
79+
80+
assert_frame_equal(df, read_json(df.to_json(orient='split'),
81+
orient='split', dtype=False))
82+
unser = read_json(df.to_json(orient='values'), orient='values')
83+
np.testing.assert_equal(df.values, unser.values)
84+
5785
def test_frame_from_json_to_json(self):
5886

5987
def _check_orient(df, orient, dtype=None, numpy=False, convert_axes=True, check_dtype=True, raise_ok=None):
@@ -236,6 +264,17 @@ def test_frame_to_json_except(self):
236264
df = DataFrame([1, 2, 3])
237265
self.assertRaises(ValueError, df.to_json, orient="garbage")
238266

267+
def test_series_non_unique_index(self):
268+
s = Series(['a', 'b'], index=[1, 1])
269+
270+
self.assertRaises(ValueError, s.to_json, orient='index')
271+
272+
assert_series_equal(s, read_json(s.to_json(orient='split'),
273+
orient='split', typ='series'))
274+
unser = read_json(s.to_json(orient='records'),
275+
orient='records', typ='series')
276+
np.testing.assert_equal(s.values, unser.values)
277+
239278
def test_series_from_json_to_json(self):
240279

241280
def _check_orient(series, orient, dtype=None, numpy=False):

0 commit comments

Comments
 (0)