Skip to content

Commit f2231ec

Browse files
committed
BUG: Fix json_normalize throwing TypeError when calling with list ecord_path pandas-dev#21605
1 parent 7bee353 commit f2231ec

File tree

3 files changed

+36
-24
lines changed

3 files changed

+36
-24
lines changed

doc/source/whatsnew/v0.23.2.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ Bug Fixes
7272

7373
- Bug in :func:`read_csv` that caused it to incorrectly raise an error when ``nrows=0``, ``low_memory=True``, and ``index_col`` was not ``None`` (:issue:`21141`)
7474
- Bug in :func:`json_normalize` when formatting the ``record_prefix`` with integer columns (:issue:`21536`)
75+
- Bug in :func:`json_normalize` when calling with list ``record_path`` (:issue:`21605`)
7576
-
7677

7778
**Plotting**

pandas/io/json/normalize.py

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,31 @@ def _pull_field(js, spec):
224224
sep = str(sep)
225225
meta_keys = [sep.join(val) for val in meta]
226226

227+
def _recursive_extract_dict(obj, key, seen_meta, level):
228+
recs = _pull_field(obj, key)
229+
230+
# For repeating the metadata later
231+
lengths.append(len(recs))
232+
233+
for val, key in zip(meta, meta_keys):
234+
if level + 1 > len(val):
235+
meta_val = seen_meta[key]
236+
else:
237+
try:
238+
meta_val = _pull_field(obj, val[level:])
239+
except KeyError as e:
240+
if errors == 'ignore':
241+
meta_val = np.nan
242+
else:
243+
raise \
244+
KeyError("Try running with "
245+
"errors='ignore' as key "
246+
"{err} is not always present"
247+
.format(err=e))
248+
meta_vals[key].append(meta_val)
249+
250+
records.extend(recs)
251+
227252
def _recursive_extract(data, path, seen_meta, level=0):
228253
if len(path) > 1:
229254
for obj in data:
@@ -233,31 +258,11 @@ def _recursive_extract(data, path, seen_meta, level=0):
233258

234259
_recursive_extract(obj[path[0]], path[1:],
235260
seen_meta, level=level + 1)
236-
else:
261+
elif isinstance(data, list):
237262
for obj in data:
238-
recs = _pull_field(obj, path[0])
239-
240-
# For repeating the metadata later
241-
lengths.append(len(recs))
242-
243-
for val, key in zip(meta, meta_keys):
244-
if level + 1 > len(val):
245-
meta_val = seen_meta[key]
246-
else:
247-
try:
248-
meta_val = _pull_field(obj, val[level:])
249-
except KeyError as e:
250-
if errors == 'ignore':
251-
meta_val = np.nan
252-
else:
253-
raise \
254-
KeyError("Try running with "
255-
"errors='ignore' as key "
256-
"{err} is not always present"
257-
.format(err=e))
258-
meta_vals[key].append(meta_val)
259-
260-
records.extend(recs)
263+
_recursive_extract_dict(obj, path[0], seen_meta, level)
264+
else:
265+
_recursive_extract_dict(data, path[0], seen_meta, level)
261266

262267
_recursive_extract(data, record_path, {}, level=0)
263268

pandas/tests/io/json/test_normalize.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ def test_value_array_record_prefix(self):
129129
expected = DataFrame([[1], [2]], columns=['Prefix.0'])
130130
tm.assert_frame_equal(result, expected)
131131

132+
def test_list_record_path(self):
133+
# GH 21605
134+
result = json_normalize({'A': {'B': [1, 2]}}, ['A', 'B'])
135+
expected = DataFrame([[1], [2]], columns=['0'])
136+
tm.assert_frame_equal(result, expected)
137+
132138
def test_more_deeply_nested(self, deep_nested):
133139

134140
result = json_normalize(deep_nested, ['states', 'cities'],

0 commit comments

Comments
 (0)