We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
DOC: Additional examples for `json_normalize`
When handling JSON data, a common use case is to start with a list of hierarchically nested records with an unknown, or possibly inconsistent, layout, and transform them into a flat tabular structure. Pandas' existing `json_normalize` function handles this use case, but the examples in the function's documentation don't make this clear. It could be useful to provide some additional explanation and examples in these functions.

#### Code Sample

```python
data = [
    ...: {'id': 1, 'name': {'first': 'Coleen', 'last': 'Volk'}},
    ...: {'name': {'given': 'Mose', 'family': 'Regner'}},
    ...: {'id': 2, 'name': 'Faye Raker'},
    ...: ]

json_normalize(data)

    id        name name.family name.first name.given name.last
0  1.0         NaN         NaN     Coleen        NaN      Volk
1  NaN         NaN      Regner        NaN       Mose       NaN
2  2.0  Faye Raker         NaN        NaN        NaN       NaN
```

#### Problem description

Direct conversion to a data frame doesn't provide information about the nested structure. `pandas.read_json` is also designed to work with data that's already flat.

The existing [documentation for `json_normalize`](http://pandas.pydata.org/pandas-docs/version/0.20/generated/pandas.io.json.json_normalize.html) only includes an example of using it for a somewhat more complicated process. The [tutorial sections on JSON parsing](http://pandas.pydata.org/pandas-docs/version/0.20/io.html#normalization) use the same example. These items could be updated to include additional examples that would help others understand when and how to apply `json_normalize`

#### Output of ``pd.show_versions()``

<details>
INSTALLED VERSIONS
------------------
commit: None
python: 3.6.1.final.0
python-bits: 64
OS: Darwin
OS-release: 16.6.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.20.1
pytest: 3.0.7
pip: 9.0.1
setuptools: 27.2.0
Cython: 0.25.2
numpy: 1.12.1
scipy: 0.19.0
xarray: None
IPython: 6.0.0
sphinx: 1.5.6
patsy: 0.4.1
dateutil: 2.6.0
pytz: 2017.2
blosc: None
bottleneck: 1.2.1
tables: 3.3.0
numexpr: 2.6.2
feather: None
matplotlib: 2.0.2
openpyxl: 2.4.7
xlrd: 1.0.0
xlwt: 1.2.0
xlsxwriter: 0.9.6
lxml: 3.7.3
bs4: 4.6.0
html5lib: 0.999
sqlalchemy: 1.1.9
pymysql: None
psycopg2: None
jinja2: 2.9.6
s3fs: None
pandas_gbq: None
pandas_datareader: None

</details>


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pandas/io/json/normalize.py`
Content:
```
1 # ---------------------------------------------------------------------
2 # JSON normalization routines
3 
4 import copy
5 from collections import defaultdict
6 import numpy as np
7 
8 from pandas._libs.lib import convert_json_to_lines
9 from pandas import compat, DataFrame
10 
11 
12 def _convert_to_line_delimits(s):
13     """Helper function that converts json lists to line delimited json."""
14 
15     # Determine we have a JSON list to turn to lines otherwise just return the
16     # json object, only lists can
17     if not s[0] == '[' and s[-1] == ']':
18         return s
19     s = s[1:-1]
20 
21     return convert_json_to_lines(s)
22 
23 
24 def nested_to_record(ds, prefix="", sep=".", level=0):
25     """a simplified json_normalize
26 
27     converts a nested dict into a flat dict ("record"), unlike json_normalize,
28     it does not attempt to extract a subset of the data.
29 
30     Parameters
31     ----------
32     ds : dict or list of dicts
33     prefix: the prefix, optional, default: ""
34     sep : string, default '.'
35         Nested records will generate names separated by sep,
36         e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar
37 
38         .. versionadded:: 0.20.0
39 
40     level: the number of levels in the jason string, optional, default: 0
41 
42     Returns
43     -------
44     d - dict or list of dicts, matching `ds`
45 
46     Examples
47     --------
48 
49     IN[52]: nested_to_record(dict(flat1=1,dict1=dict(c=1,d=2),
50                                   nested=dict(e=dict(c=1,d=2),d=2)))
51     Out[52]:
52     {'dict1.c': 1,
53      'dict1.d': 2,
54      'flat1': 1,
55      'nested.d': 2,
56      'nested.e.c': 1,
57      'nested.e.d': 2}
58     """
59     singleton = False
60     if isinstance(ds, dict):
61         ds = [ds]
62         singleton = True
63 
64     new_ds = []
65     for d in ds:
66 
67         new_d = copy.deepcopy(d)
68         for k, v in d.items():
69             # each key gets renamed with prefix
70             if not isinstance(k, compat.string_types):
71                 k = str(k)
72             if level == 0:
73                 newkey = k
74             else:
75                 newkey = prefix + sep + k
76 
77             # only dicts gets recurse-flattend
78             # only at level>1 do we rename the rest of the keys
79             if not isinstance(v, dict):
80                 if level != 0:  # so we skip copying for top level, common case
81                     v = new_d.pop(k)
82                     new_d[newkey] = v
83                 continue
84             else:
85                 v = new_d.pop(k)
86                 new_d.update(nested_to_record(v, newkey, sep, level + 1))
87         new_ds.append(new_d)
88 
89     if singleton:
90         return new_ds[0]
91     return new_ds
92 
93 
94 def json_normalize(data, record_path=None, meta=None,
95                    meta_prefix=None,
96                    record_prefix=None,
97                    errors='raise',
98                    sep='.'):
99     """
100     "Normalize" semi-structured JSON data into a flat table
101 
102     Parameters
103     ----------
104     data : dict or list of dicts
105         Unserialized JSON objects
106     record_path : string or list of strings, default None
107         Path in each object to list of records. If not passed, data will be
108         assumed to be an array of records
109     meta : list of paths (string or list of strings), default None
110         Fields to use as metadata for each record in resulting table
111     record_prefix : string, default None
112         If True, prefix records with dotted (?) path, e.g. foo.bar.field if
113         path to records is ['foo', 'bar']
114     meta_prefix : string, default None
115     errors : {'raise', 'ignore'}, default 'raise'
116 
117         * 'ignore' : will ignore KeyError if keys listed in meta are not
118           always present
119         * 'raise' : will raise KeyError if keys listed in meta are not
120           always present
121 
122         .. versionadded:: 0.20.0
123 
124     sep : string, default '.'
125         Nested records will generate names separated by sep,
126         e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar
127 
128         .. versionadded:: 0.20.0
129 
130 
131     Returns
132     -------
133     frame : DataFrame
134 
135     Examples
136     --------
137 
138     >>> data = [{'state': 'Florida',
139     ...          'shortname': 'FL',
140     ...          'info': {
141     ...               'governor': 'Rick Scott'
142     ...          },
143     ...          'counties': [{'name': 'Dade', 'population': 12345},
144     ...                      {'name': 'Broward', 'population': 40000},
145     ...                      {'name': 'Palm Beach', 'population': 60000}]},
146     ...         {'state': 'Ohio',
147     ...          'shortname': 'OH',
148     ...          'info': {
149     ...               'governor': 'John Kasich'
150     ...          },
151     ...          'counties': [{'name': 'Summit', 'population': 1234},
152     ...                       {'name': 'Cuyahoga', 'population': 1337}]}]
153     >>> from pandas.io.json import json_normalize
154     >>> result = json_normalize(data, 'counties', ['state', 'shortname',
155     ...                                           ['info', 'governor']])
156     >>> result
157              name  population info.governor    state shortname
158     0        Dade       12345    Rick Scott  Florida        FL
159     1     Broward       40000    Rick Scott  Florida        FL
160     2  Palm Beach       60000    Rick Scott  Florida        FL
161     3      Summit        1234   John Kasich     Ohio        OH
162     4    Cuyahoga        1337   John Kasich     Ohio        OH
163 
164     """
165     def _pull_field(js, spec):
166         result = js
167         if isinstance(spec, list):
168             for field in spec:
169                 result = result[field]
170         else:
171             result = result[spec]
172 
173         return result
174 
175     if isinstance(data, list) and len(data) is 0:
176         return DataFrame()
177 
178     # A bit of a hackjob
179     if isinstance(data, dict):
180         data = [data]
181 
182     if record_path is None:
183         if any([isinstance(x, dict) for x in compat.itervalues(data[0])]):
184             # naive normalization, this is idempotent for flat records
185             # and potentially will inflate the data considerably for
186             # deeply nested structures:
187             #  {VeryLong: { b: 1,c:2}} -> {VeryLong.b:1 ,VeryLong.c:@}
188             #
189             # TODO: handle record value which are lists, at least error
190             #       reasonably
191             data = nested_to_record(data, sep=sep)
192         return DataFrame(data)
193     elif not isinstance(record_path, list):
194         record_path = [record_path]
195 
196     if meta is None:
197         meta = []
198     elif not isinstance(meta, list):
199         meta = [meta]
200 
201     for i, x in enumerate(meta):
202         if not isinstance(x, list):
203             meta[i] = [x]
204 
205     # Disastrously inefficient for now
206     records = []
207     lengths = []
208 
209     meta_vals = defaultdict(list)
210     if not isinstance(sep, compat.string_types):
211         sep = str(sep)
212     meta_keys = [sep.join(val) for val in meta]
213 
214     def _recursive_extract(data, path, seen_meta, level=0):
215         if len(path) > 1:
216             for obj in data:
217                 for val, key in zip(meta, meta_keys):
218                     if level + 1 == len(val):
219                         seen_meta[key] = _pull_field(obj, val[-1])
220 
221                 _recursive_extract(obj[path[0]], path[1:],
222                                    seen_meta, level=level + 1)
223         else:
224             for obj in data:
225                 recs = _pull_field(obj, path[0])
226 
227                 # For repeating the metadata later
228                 lengths.append(len(recs))
229 
230                 for val, key in zip(meta, meta_keys):
231                     if level + 1 > len(val):
232                         meta_val = seen_meta[key]
233                     else:
234                         try:
235                             meta_val = _pull_field(obj, val[level:])
236                         except KeyError as e:
237                             if errors == 'ignore':
238                                 meta_val = np.nan
239                             else:
240                                 raise \
241                                     KeyError("Try running with "
242                                              "errors='ignore' as key "
243                                              "%s is not always present", e)
244                     meta_vals[key].append(meta_val)
245 
246                 records.extend(recs)
247 
248     _recursive_extract(data, record_path, {}, level=0)
249 
250     result = DataFrame(records)
251 
252     if record_prefix is not None:
253         result.rename(columns=lambda x: record_prefix + x, inplace=True)
254 
255     # Data types, a problem
256     for k, v in compat.iteritems(meta_vals):
257         if meta_prefix is not None:
258             k = meta_prefix + k
259 
260         if k in result:
261             raise ValueError('Conflicting metadata name %s, '
262                              'need distinguishing prefix ' % k)
263 
264         result[k] = np.array(v).repeat(lengths)
265 
266     return result
267
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pandas/io/json/normalize.py b/pandas/io/json/normalize.py
--- a/pandas/io/json/normalize.py
+++ b/pandas/io/json/normalize.py
@@ -135,6 +135,16 @@
     Examples
     --------
 
+    >>> from pandas.io.json import json_normalize
+    >>> data = [{'id': 1, 'name': {'first': 'Coleen', 'last': 'Volk'}},
+    ...         {'name': {'given': 'Mose', 'family': 'Regner'}},
+    ...         {'id': 2, 'name': 'Faye Raker'}]
+    >>> json_normalize(data)
+        id        name name.family name.first name.given name.last
+    0  1.0         NaN         NaN     Coleen        NaN      Volk
+    1  NaN         NaN      Regner        NaN       Mose       NaN
+    2  2.0  Faye Raker         NaN        NaN        NaN       NaN
+
     >>> data = [{'state': 'Florida',
     ...          'shortname': 'FL',
     ...          'info': {
@@ -150,7 +160,6 @@
     ...          },
     ...          'counties': [{'name': 'Summit', 'population': 1234},
     ...                       {'name': 'Cuyahoga', 'population': 1337}]}]
-    >>> from pandas.io.json import json_normalize
     >>> result = json_normalize(data, 'counties', ['state', 'shortname',
     ...                                           ['info', 'governor']])
     >>> result

{"golden_diff": "diff --git a/pandas/io/json/normalize.py b/pandas/io/json/normalize.py\n--- a/pandas/io/json/normalize.py\n+++ b/pandas/io/json/normalize.py\n@@ -135,6 +135,16 @@\n     Examples\n     --------\n \n+    >>> from pandas.io.json import json_normalize\n+    >>> data = [{'id': 1, 'name': {'first': 'Coleen', 'last': 'Volk'}},\n+    ...         {'name': {'given': 'Mose', 'family': 'Regner'}},\n+    ...         {'id': 2, 'name': 'Faye Raker'}]\n+    >>> json_normalize(data)\n+        id        name name.family name.first name.given name.last\n+    0  1.0         NaN         NaN     Coleen        NaN      Volk\n+    1  NaN         NaN      Regner        NaN       Mose       NaN\n+    2  2.0  Faye Raker         NaN        NaN        NaN       NaN\n+\n     >>> data = [{'state': 'Florida',\n     ...          'shortname': 'FL',\n     ...          'info': {\n@@ -150,7 +160,6 @@\n     ...          },\n     ...          'counties': [{'name': 'Summit', 'population': 1234},\n     ...                       {'name': 'Cuyahoga', 'population': 1337}]}]\n-    >>> from pandas.io.json import json_normalize\n     >>> result = json_normalize(data, 'counties', ['state', 'shortname',\n     ...                                           ['info', 'governor']])\n     >>> result\n", "issue": "DOC: Additional examples for `json_normalize`\nWhen handling JSON data, a common use case is to start with a list of hierarchically nested records with an unknown, or possibly inconsistent, layout, and transform them into a flat tabular structure. Pandas' existing `json_normalize` function handles this use case, but the examples in the function's documentation don't make this clear. It could be useful to provide some additional explanation and examples in these functions.\r\n\r\n#### Code Sample\r\n\r\n```python\r\ndata = [\r\n    ...: {'id': 1, 'name': {'first': 'Coleen', 'last': 'Volk'}},\r\n    ...: {'name': {'given': 'Mose', 'family': 'Regner'}},\r\n    ...: {'id': 2, 'name': 'Faye Raker'},\r\n    ...: ]\r\n\r\njson_normalize(data)\r\n\r\n    id        name name.family name.first name.given name.last\r\n0  1.0         NaN         NaN     Coleen        NaN      Volk\r\n1  NaN         NaN      Regner        NaN       Mose       NaN\r\n2  2.0  Faye Raker         NaN        NaN        NaN       NaN\r\n```\r\n\r\n#### Problem description\r\n\r\nDirect conversion to a data frame doesn't provide information about the nested structure. `pandas.read_json` is also designed to work with data that's already flat.\r\n\r\nThe existing [documentation for `json_normalize`](http://pandas.pydata.org/pandas-docs/version/0.20/generated/pandas.io.json.json_normalize.html) only includes an example of using it for a somewhat more complicated process. The [tutorial sections on JSON parsing](http://pandas.pydata.org/pandas-docs/version/0.20/io.html#normalization) use the same example. These items could be updated to include additional examples that would help others understand when and how to apply `json_normalize`\r\n\r\n#### Output of ``pd.show_versions()``\r\n\r\n<details>\r\nINSTALLED VERSIONS\r\n------------------\r\ncommit: None\r\npython: 3.6.1.final.0\r\npython-bits: 64\r\nOS: Darwin\r\nOS-release: 16.6.0\r\nmachine: x86_64\r\nprocessor: i386\r\nbyteorder: little\r\nLC_ALL: None\r\nLANG: en_US.UTF-8\r\nLOCALE: en_US.UTF-8\r\n\r\npandas: 0.20.1\r\npytest: 3.0.7\r\npip: 9.0.1\r\nsetuptools: 27.2.0\r\nCython: 0.25.2\r\nnumpy: 1.12.1\r\nscipy: 0.19.0\r\nxarray: None\r\nIPython: 6.0.0\r\nsphinx: 1.5.6\r\npatsy: 0.4.1\r\ndateutil: 2.6.0\r\npytz: 2017.2\r\nblosc: None\r\nbottleneck: 1.2.1\r\ntables: 3.3.0\r\nnumexpr: 2.6.2\r\nfeather: None\r\nmatplotlib: 2.0.2\r\nopenpyxl: 2.4.7\r\nxlrd: 1.0.0\r\nxlwt: 1.2.0\r\nxlsxwriter: 0.9.6\r\nlxml: 3.7.3\r\nbs4: 4.6.0\r\nhtml5lib: 0.999\r\nsqlalchemy: 1.1.9\r\npymysql: None\r\npsycopg2: None\r\njinja2: 2.9.6\r\ns3fs: None\r\npandas_gbq: None\r\npandas_datareader: None\r\n\r\n</details>\r\n\n", "before_files": [{"content": "# ---------------------------------------------------------------------\n# JSON normalization routines\n\nimport copy\nfrom collections import defaultdict\nimport numpy as np\n\nfrom pandas._libs.lib import convert_json_to_lines\nfrom pandas import compat, DataFrame\n\n\ndef _convert_to_line_delimits(s):\n    \"\"\"Helper function that converts json lists to line delimited json.\"\"\"\n\n    # Determine we have a JSON list to turn to lines otherwise just return the\n    # json object, only lists can\n    if not s[0] == '[' and s[-1] == ']':\n        return s\n    s = s[1:-1]\n\n    return convert_json_to_lines(s)\n\n\ndef nested_to_record(ds, prefix=\"\", sep=\".\", level=0):\n    \"\"\"a simplified json_normalize\n\n    converts a nested dict into a flat dict (\"record\"), unlike json_normalize,\n    it does not attempt to extract a subset of the data.\n\n    Parameters\n    ----------\n    ds : dict or list of dicts\n    prefix: the prefix, optional, default: \"\"\n    sep : string, default '.'\n        Nested records will generate names separated by sep,\n        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar\n\n        .. versionadded:: 0.20.0\n\n    level: the number of levels in the jason string, optional, default: 0\n\n    Returns\n    -------\n    d - dict or list of dicts, matching `ds`\n\n    Examples\n    --------\n\n    IN[52]: nested_to_record(dict(flat1=1,dict1=dict(c=1,d=2),\n                                  nested=dict(e=dict(c=1,d=2),d=2)))\n    Out[52]:\n    {'dict1.c': 1,\n     'dict1.d': 2,\n     'flat1': 1,\n     'nested.d': 2,\n     'nested.e.c': 1,\n     'nested.e.d': 2}\n    \"\"\"\n    singleton = False\n    if isinstance(ds, dict):\n        ds = [ds]\n        singleton = True\n\n    new_ds = []\n    for d in ds:\n\n        new_d = copy.deepcopy(d)\n        for k, v in d.items():\n            # each key gets renamed with prefix\n            if not isinstance(k, compat.string_types):\n                k = str(k)\n            if level == 0:\n                newkey = k\n            else:\n                newkey = prefix + sep + k\n\n            # only dicts gets recurse-flattend\n            # only at level>1 do we rename the rest of the keys\n            if not isinstance(v, dict):\n                if level != 0:  # so we skip copying for top level, common case\n                    v = new_d.pop(k)\n                    new_d[newkey] = v\n                continue\n            else:\n                v = new_d.pop(k)\n                new_d.update(nested_to_record(v, newkey, sep, level + 1))\n        new_ds.append(new_d)\n\n    if singleton:\n        return new_ds[0]\n    return new_ds\n\n\ndef json_normalize(data, record_path=None, meta=None,\n                   meta_prefix=None,\n                   record_prefix=None,\n                   errors='raise',\n                   sep='.'):\n    \"\"\"\n    \"Normalize\" semi-structured JSON data into a flat table\n\n    Parameters\n    ----------\n    data : dict or list of dicts\n        Unserialized JSON objects\n    record_path : string or list of strings, default None\n        Path in each object to list of records. If not passed, data will be\n        assumed to be an array of records\n    meta : list of paths (string or list of strings), default None\n        Fields to use as metadata for each record in resulting table\n    record_prefix : string, default None\n        If True, prefix records with dotted (?) path, e.g. foo.bar.field if\n        path to records is ['foo', 'bar']\n    meta_prefix : string, default None\n    errors : {'raise', 'ignore'}, default 'raise'\n\n        * 'ignore' : will ignore KeyError if keys listed in meta are not\n          always present\n        * 'raise' : will raise KeyError if keys listed in meta are not\n          always present\n\n        .. versionadded:: 0.20.0\n\n    sep : string, default '.'\n        Nested records will generate names separated by sep,\n        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar\n\n        .. versionadded:: 0.20.0\n\n\n    Returns\n    -------\n    frame : DataFrame\n\n    Examples\n    --------\n\n    >>> data = [{'state': 'Florida',\n    ...          'shortname': 'FL',\n    ...          'info': {\n    ...               'governor': 'Rick Scott'\n    ...          },\n    ...          'counties': [{'name': 'Dade', 'population': 12345},\n    ...                      {'name': 'Broward', 'population': 40000},\n    ...                      {'name': 'Palm Beach', 'population': 60000}]},\n    ...         {'state': 'Ohio',\n    ...          'shortname': 'OH',\n    ...          'info': {\n    ...               'governor': 'John Kasich'\n    ...          },\n    ...          'counties': [{'name': 'Summit', 'population': 1234},\n    ...                       {'name': 'Cuyahoga', 'population': 1337}]}]\n    >>> from pandas.io.json import json_normalize\n    >>> result = json_normalize(data, 'counties', ['state', 'shortname',\n    ...                                           ['info', 'governor']])\n    >>> result\n             name  population info.governor    state shortname\n    0        Dade       12345    Rick Scott  Florida        FL\n    1     Broward       40000    Rick Scott  Florida        FL\n    2  Palm Beach       60000    Rick Scott  Florida        FL\n    3      Summit        1234   John Kasich     Ohio        OH\n    4    Cuyahoga        1337   John Kasich     Ohio        OH\n\n    \"\"\"\n    def _pull_field(js, spec):\n        result = js\n        if isinstance(spec, list):\n            for field in spec:\n                result = result[field]\n        else:\n            result = result[spec]\n\n        return result\n\n    if isinstance(data, list) and len(data) is 0:\n        return DataFrame()\n\n    # A bit of a hackjob\n    if isinstance(data, dict):\n        data = [data]\n\n    if record_path is None:\n        if any([isinstance(x, dict) for x in compat.itervalues(data[0])]):\n            # naive normalization, this is idempotent for flat records\n            # and potentially will inflate the data considerably for\n            # deeply nested structures:\n            #  {VeryLong: { b: 1,c:2}} -> {VeryLong.b:1 ,VeryLong.c:@}\n            #\n            # TODO: handle record value which are lists, at least error\n            #       reasonably\n            data = nested_to_record(data, sep=sep)\n        return DataFrame(data)\n    elif not isinstance(record_path, list):\n        record_path = [record_path]\n\n    if meta is None:\n        meta = []\n    elif not isinstance(meta, list):\n        meta = [meta]\n\n    for i, x in enumerate(meta):\n        if not isinstance(x, list):\n            meta[i] = [x]\n\n    # Disastrously inefficient for now\n    records = []\n    lengths = []\n\n    meta_vals = defaultdict(list)\n    if not isinstance(sep, compat.string_types):\n        sep = str(sep)\n    meta_keys = [sep.join(val) for val in meta]\n\n    def _recursive_extract(data, path, seen_meta, level=0):\n        if len(path) > 1:\n            for obj in data:\n                for val, key in zip(meta, meta_keys):\n                    if level + 1 == len(val):\n                        seen_meta[key] = _pull_field(obj, val[-1])\n\n                _recursive_extract(obj[path[0]], path[1:],\n                                   seen_meta, level=level + 1)\n        else:\n            for obj in data:\n                recs = _pull_field(obj, path[0])\n\n                # For repeating the metadata later\n                lengths.append(len(recs))\n\n                for val, key in zip(meta, meta_keys):\n                    if level + 1 > len(val):\n                        meta_val = seen_meta[key]\n                    else:\n                        try:\n                            meta_val = _pull_field(obj, val[level:])\n                        except KeyError as e:\n                            if errors == 'ignore':\n                                meta_val = np.nan\n                            else:\n                                raise \\\n                                    KeyError(\"Try running with \"\n                                             \"errors='ignore' as key \"\n                                             \"%s is not always present\", e)\n                    meta_vals[key].append(meta_val)\n\n                records.extend(recs)\n\n    _recursive_extract(data, record_path, {}, level=0)\n\n    result = DataFrame(records)\n\n    if record_prefix is not None:\n        result.rename(columns=lambda x: record_prefix + x, inplace=True)\n\n    # Data types, a problem\n    for k, v in compat.iteritems(meta_vals):\n        if meta_prefix is not None:\n            k = meta_prefix + k\n\n        if k in result:\n            raise ValueError('Conflicting metadata name %s, '\n                             'need distinguishing prefix ' % k)\n\n        result[k] = np.array(v).repeat(lengths)\n\n    return result\n", "path": "pandas/io/json/normalize.py"}], "after_files": [{"content": "# ---------------------------------------------------------------------\n# JSON normalization routines\n\nimport copy\nfrom collections import defaultdict\nimport numpy as np\n\nfrom pandas._libs.lib import convert_json_to_lines\nfrom pandas import compat, DataFrame\n\n\ndef _convert_to_line_delimits(s):\n    \"\"\"Helper function that converts json lists to line delimited json.\"\"\"\n\n    # Determine we have a JSON list to turn to lines otherwise just return the\n    # json object, only lists can\n    if not s[0] == '[' and s[-1] == ']':\n        return s\n    s = s[1:-1]\n\n    return convert_json_to_lines(s)\n\n\ndef nested_to_record(ds, prefix=\"\", sep=\".\", level=0):\n    \"\"\"a simplified json_normalize\n\n    converts a nested dict into a flat dict (\"record\"), unlike json_normalize,\n    it does not attempt to extract a subset of the data.\n\n    Parameters\n    ----------\n    ds : dict or list of dicts\n    prefix: the prefix, optional, default: \"\"\n    sep : string, default '.'\n        Nested records will generate names separated by sep,\n        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar\n\n        .. versionadded:: 0.20.0\n\n    level: the number of levels in the jason string, optional, default: 0\n\n    Returns\n    -------\n    d - dict or list of dicts, matching `ds`\n\n    Examples\n    --------\n\n    IN[52]: nested_to_record(dict(flat1=1,dict1=dict(c=1,d=2),\n                                  nested=dict(e=dict(c=1,d=2),d=2)))\n    Out[52]:\n    {'dict1.c': 1,\n     'dict1.d': 2,\n     'flat1': 1,\n     'nested.d': 2,\n     'nested.e.c': 1,\n     'nested.e.d': 2}\n    \"\"\"\n    singleton = False\n    if isinstance(ds, dict):\n        ds = [ds]\n        singleton = True\n\n    new_ds = []\n    for d in ds:\n\n        new_d = copy.deepcopy(d)\n        for k, v in d.items():\n            # each key gets renamed with prefix\n            if not isinstance(k, compat.string_types):\n                k = str(k)\n            if level == 0:\n                newkey = k\n            else:\n                newkey = prefix + sep + k\n\n            # only dicts gets recurse-flattend\n            # only at level>1 do we rename the rest of the keys\n            if not isinstance(v, dict):\n                if level != 0:  # so we skip copying for top level, common case\n                    v = new_d.pop(k)\n                    new_d[newkey] = v\n                continue\n            else:\n                v = new_d.pop(k)\n                new_d.update(nested_to_record(v, newkey, sep, level + 1))\n        new_ds.append(new_d)\n\n    if singleton:\n        return new_ds[0]\n    return new_ds\n\n\ndef json_normalize(data, record_path=None, meta=None,\n                   meta_prefix=None,\n                   record_prefix=None,\n                   errors='raise',\n                   sep='.'):\n    \"\"\"\n    \"Normalize\" semi-structured JSON data into a flat table\n\n    Parameters\n    ----------\n    data : dict or list of dicts\n        Unserialized JSON objects\n    record_path : string or list of strings, default None\n        Path in each object to list of records. If not passed, data will be\n        assumed to be an array of records\n    meta : list of paths (string or list of strings), default None\n        Fields to use as metadata for each record in resulting table\n    record_prefix : string, default None\n        If True, prefix records with dotted (?) path, e.g. foo.bar.field if\n        path to records is ['foo', 'bar']\n    meta_prefix : string, default None\n    errors : {'raise', 'ignore'}, default 'raise'\n\n        * 'ignore' : will ignore KeyError if keys listed in meta are not\n          always present\n        * 'raise' : will raise KeyError if keys listed in meta are not\n          always present\n\n        .. versionadded:: 0.20.0\n\n    sep : string, default '.'\n        Nested records will generate names separated by sep,\n        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar\n\n        .. versionadded:: 0.20.0\n\n\n    Returns\n    -------\n    frame : DataFrame\n\n    Examples\n    --------\n\n    >>> from pandas.io.json import json_normalize\n    >>> data = [{'id': 1, 'name': {'first': 'Coleen', 'last': 'Volk'}},\n    ...         {'name': {'given': 'Mose', 'family': 'Regner'}},\n    ...         {'id': 2, 'name': 'Faye Raker'}]\n    >>> json_normalize(data)\n        id        name name.family name.first name.given name.last\n    0  1.0         NaN         NaN     Coleen        NaN      Volk\n    1  NaN         NaN      Regner        NaN       Mose       NaN\n    2  2.0  Faye Raker         NaN        NaN        NaN       NaN\n\n    >>> data = [{'state': 'Florida',\n    ...          'shortname': 'FL',\n    ...          'info': {\n    ...               'governor': 'Rick Scott'\n    ...          },\n    ...          'counties': [{'name': 'Dade', 'population': 12345},\n    ...                      {'name': 'Broward', 'population': 40000},\n    ...                      {'name': 'Palm Beach', 'population': 60000}]},\n    ...         {'state': 'Ohio',\n    ...          'shortname': 'OH',\n    ...          'info': {\n    ...               'governor': 'John Kasich'\n    ...          },\n    ...          'counties': [{'name': 'Summit', 'population': 1234},\n    ...                       {'name': 'Cuyahoga', 'population': 1337}]}]\n    >>> result = json_normalize(data, 'counties', ['state', 'shortname',\n    ...                                           ['info', 'governor']])\n    >>> result\n             name  population info.governor    state shortname\n    0        Dade       12345    Rick Scott  Florida        FL\n    1     Broward       40000    Rick Scott  Florida        FL\n    2  Palm Beach       60000    Rick Scott  Florida        FL\n    3      Summit        1234   John Kasich     Ohio        OH\n    4    Cuyahoga        1337   John Kasich     Ohio        OH\n\n    \"\"\"\n    def _pull_field(js, spec):\n        result = js\n        if isinstance(spec, list):\n            for field in spec:\n                result = result[field]\n        else:\n            result = result[spec]\n\n        return result\n\n    if isinstance(data, list) and len(data) is 0:\n        return DataFrame()\n\n    # A bit of a hackjob\n    if isinstance(data, dict):\n        data = [data]\n\n    if record_path is None:\n        if any([isinstance(x, dict) for x in compat.itervalues(data[0])]):\n            # naive normalization, this is idempotent for flat records\n            # and potentially will inflate the data considerably for\n            # deeply nested structures:\n            #  {VeryLong: { b: 1,c:2}} -> {VeryLong.b:1 ,VeryLong.c:@}\n            #\n            # TODO: handle record value which are lists, at least error\n            #       reasonably\n            data = nested_to_record(data, sep=sep)\n        return DataFrame(data)\n    elif not isinstance(record_path, list):\n        record_path = [record_path]\n\n    if meta is None:\n        meta = []\n    elif not isinstance(meta, list):\n        meta = [meta]\n\n    for i, x in enumerate(meta):\n        if not isinstance(x, list):\n            meta[i] = [x]\n\n    # Disastrously inefficient for now\n    records = []\n    lengths = []\n\n    meta_vals = defaultdict(list)\n    if not isinstance(sep, compat.string_types):\n        sep = str(sep)\n    meta_keys = [sep.join(val) for val in meta]\n\n    def _recursive_extract(data, path, seen_meta, level=0):\n        if len(path) > 1:\n            for obj in data:\n                for val, key in zip(meta, meta_keys):\n                    if level + 1 == len(val):\n                        seen_meta[key] = _pull_field(obj, val[-1])\n\n                _recursive_extract(obj[path[0]], path[1:],\n                                   seen_meta, level=level + 1)\n        else:\n            for obj in data:\n                recs = _pull_field(obj, path[0])\n\n                # For repeating the metadata later\n                lengths.append(len(recs))\n\n                for val, key in zip(meta, meta_keys):\n                    if level + 1 > len(val):\n                        meta_val = seen_meta[key]\n                    else:\n                        try:\n                            meta_val = _pull_field(obj, val[level:])\n                        except KeyError as e:\n                            if errors == 'ignore':\n                                meta_val = np.nan\n                            else:\n                                raise \\\n                                    KeyError(\"Try running with \"\n                                             \"errors='ignore' as key \"\n                                             \"%s is not always present\", e)\n                    meta_vals[key].append(meta_val)\n\n                records.extend(recs)\n\n    _recursive_extract(data, record_path, {}, level=0)\n\n    result = DataFrame(records)\n\n    if record_prefix is not None:\n        result.rename(columns=lambda x: record_prefix + x, inplace=True)\n\n    # Data types, a problem\n    for k, v in compat.iteritems(meta_vals):\n        if meta_prefix is not None:\n            k = meta_prefix + k\n\n        if k in result:\n            raise ValueError('Conflicting metadata name %s, '\n                             'need distinguishing prefix ' % k)\n\n        result[k] = np.array(v).repeat(lengths)\n\n    return result\n", "path": "pandas/io/json/normalize.py"}]}