pandas json_normalize all columns have nested dictionaries flattening

10,630

Solution 1

I think using json_normalize's record_path parameter will solve your problem. Since record_path is intended to be a single path to a list of json objects or records, I had to call json_normalize more than once and then concatenate the results to get a dataframe with the data you want. You can also experiment with the record_prefix parameter to set the column naming convention. Hope this helps!

from pandas.io.json import json_normalize
from io import StringIO
import requests

word = 'slack'
url =  'https://googledictionaryapi.eu-gb.mybluemix.net/?define=' + word
response = requests.get(url)
content = response.content.decode('utf-8') # list of ugly strings
j = json.loads(content) # json list having nested dictionary
j = j[0]

df_adj = json_normalize(data=j['meaning'], record_path=["adjective"], record_prefix="adjective.")
df_verb = json_normalize(data=j['meaning'], record_path=["verb"], record_prefix="verb.")
df_adv = json_normalize(data=j['meaning'], record_path=["adverb"], record_prefix="adverb.")
df_noun = json_normalize(data=j['meaning'], record_path=["noun"], record_prefix="noun.")

df = pd.concat([df_adj, df_verb, df_adv, df_noun], axis=1)
print(df.head(3))

Solution 2

Actually the idea of 12 columns deemed to be not the best one, then after playing with the code little a while I came up with much better looking result.

import numpy as np
import pandas as pd
import json
from pandas.io.json import json_normalize
import requests

word = 'slack'
url =  'https://googledictionaryapi.eu-gb.mybluemix.net/?define=' + word
response = requests.get(url)
content = response.content.decode('utf-8') # list of ugly strings
data = json.loads(content) # json list having nested dictionary
data = data[0]

df = pd.DataFrame()
for i in data['meaning'].keys():
    x = json_normalize(data=data['meaning'][i])
    x['part_of_speech'] = i
    df = df.append(x,sort=False)

df = df[['part_of_speech', 'definition', 'example',  'synonyms']]
df

Gives the result:

    part_of_speech  definition  example synonyms
0   adjective   Not taut or held tightly in position; loose.    a slack rope    [loose, limp, not taut, not tight, hanging, fl...
1   adjective   (of business) characterized by a lack of work ...   business was rather slack   NaN
2   adjective   Having or showing laziness or negligence.   slack accounting procedures [lax, negligent, neglectful, remiss, careless,...
3   adjective   (of a tide) neither ebbing nor flowing. soon the water will become slack, and the tide...   NaN
0   noun    The part of a rope or line which is not held t...   I picked up the rod and wound in the slack  [looseness, play, give]
1   noun    Casual trousers.    NaN NaN
2   noun    A spell of inactivity or laziness.  he slept deeply, refreshed by a little slack i...   [lull, pause, respite, spell of inactivity, in...
0   verb    Loosen (something, especially a rope).  NaN NaN
1   verb    Decrease or reduce in intensity, quantity, or ...   the flow of blood slacked off   [reduce, lessen, slacken, slow, ease off, ease...
2   verb    Work slowly or lazily.  she reprimanded her girls if they were slacking [idle, shirk, be inactive, be lazy, be indolen...
3   verb    Slake (lime).   NaN NaN
0   adverb  Loosely.    their heads were hanging slack in attitudes of...   NaN

Solution 3

Kind of a messy solution, but I think it works. Starting with j as your example dictionary:

res = pd.concat([json_normalize(v, meta=['definition', 'example', 'synonyms']).add_prefix(k + '_')
                 for k, v in j['meaning'].items()], 
                axis=1)

# The output is super wide and hard to read in console output,
# but hopefully this confirms the output is (close to) what you need
res
                                                adjective_definition  \
0                       Not taut or held tightly in position; loose.   
1  (of business) characterized by a lack of work or activity; quiet.   
2                          Having or showing laziness or negligence.   
3                            (of a tide) neither ebbing nor flowing.   

                                          adjective_example  \
0                                              a slack rope   
1                                 business was rather slack   
2                               slack accounting procedures   
3  soon the water will become slack, and the tide will turn   

                                                                adjective_synonyms  \
0                            [loose, limp, not taut, not tight, hanging, flapping]   
1                                                                              NaN   
2  [lax, negligent, neglectful, remiss, careless, slapdash, slipshod, lackadais...   
3                                                                              NaN   

                                                                noun_definition  \
0  The part of a rope or line which is not held taut; the loose or unused part.   
1                                                              Casual trousers.   
2                                            A spell of inactivity or laziness.   
3                                                                           NaN   

                                                        noun_example  \
0                         I picked up the rod and wound in the slack   
1                                                                NaN   
2  he slept deeply, refreshed by a little slack in the daily routine   
3                                                                NaN   

                                                                     noun_synonyms  \
0                                                          [looseness, play, give]   
1                                                                              NaN   
2  [lull, pause, respite, spell of inactivity, interval, break, hiatus, breathi...   
3                                                                              NaN   

                                        verb_definition  \
0                Loosen (something, especially a rope).   
1  Decrease or reduce in intensity, quantity, or speed.   
2                                Work slowly or lazily.   
3                                         Slake (lime).   

                                      verb_example  \
0                                              NaN   
1                    the flow of blood slacked off   
2  she reprimanded her girls if they were slacking   
3                                              NaN   

                                                                     verb_synonyms  \
0                                                                              NaN   
1                               [reduce, lessen, slacken, slow, ease off, ease up]   
2  [idle, shirk, be inactive, be lazy, be indolent, sit back and do nothing, wa...   
3                                                                              NaN   

  adverb_definition                                          adverb_example  
0          Loosely.  their heads were hanging slack in attitudes of despair  
1               NaN                                                     NaN  
2               NaN                                                     NaN  
3               NaN                                                     NaN  
Share:
10,630

Related videos on Youtube

BhishanPoudel
Author by

BhishanPoudel

Data Scientist II at Amerisourcebergen Ph.D. Astrophysics

Updated on June 04, 2022

Comments

  • BhishanPoudel
    BhishanPoudel almost 2 years

    I have a nested dictionary (json) which was returned from the unofficial google dictionary API.

    Which looks like this:

    {'word': 'slack',
     'phonetic': '/slak/',
     'meaning': {'adjective': [{'definition': 'Not taut or held tightly in position; loose.',
        'example': 'a slack rope',
        'synonyms': ['loose',
         'limp',
         'not taut',
         'not tight',
         'hanging',
         'flapping']},
       {'definition': '(of business) characterized by a lack of work or activity; quiet.',
        'example': 'business was rather slack'},
       {'definition': 'Having or showing laziness or negligence.',
        'example': 'slack accounting procedures',
        'synonyms': ['lax',
         'negligent',
         'neglectful',
         'remiss',
         'careless',
         'slapdash',
         'slipshod',
         'lackadaisical',
         'lazy',
         'inefficient',
         'incompetent',
         'inattentive',
         'offhand',
         'casual',
         'disorderly',
         'disorganized']},
       {'definition': '(of a tide) neither ebbing nor flowing.',
        'example': 'soon the water will become slack, and the tide will turn'}],
      'noun': [{'definition': 'The part of a rope or line which is not held taut; the loose or unused part.',
        'example': 'I picked up the rod and wound in the slack',
        'synonyms': ['looseness', 'play', 'give']},
       {'definition': 'Casual trousers.'},
       {'definition': 'A spell of inactivity or laziness.',
        'example': 'he slept deeply, refreshed by a little slack in the daily routine',
        'synonyms': ['lull',
         'pause',
         'respite',
         'spell of inactivity',
         'interval',
         'break',
         'hiatus',
         'breathing space']}],
      'verb': [{'definition': 'Loosen (something, especially a rope).'},
       {'definition': 'Decrease or reduce in intensity, quantity, or speed.',
        'example': 'the flow of blood slacked off',
        'synonyms': ['reduce',
         'lessen',
         'slacken',
         'slow',
         'ease off',
         'ease up']},
       {'definition': 'Work slowly or lazily.',
        'example': 'she reprimanded her girls if they were slacking',
        'synonyms': ['idle',
         'shirk',
         'be inactive',
         'be lazy',
         'be indolent',
         'sit back and do nothing',
         'waste time',
         'lounge about']},
       {'definition': 'Slake (lime).'}],
      'adverb': [{'definition': 'Loosely.',
        'example': 'their heads were hanging slack in attitudes of despair'}]}}
    

    This is the meaning of the word slack. To get this meaning we can google the meaning or simply use the following code:

    import numpy as np
    import pandas as pd
    import json
    from pandas.io.json import json_normalize
    from io import StringIO
    import requests
    
    word = 'slack'
    url =  'https://googledictionaryapi.eu-gb.mybluemix.net/?define=' + word
    response = requests.get(url)
    content = response.content.decode('utf-8') # list of ugly strings
    j = json.loads(content) # json list having nested dictionary
    j = j[0]
    j
    

    Now, the dictionary j has three keys.

    j.keys() # dict_keys(['word', 'phonetic', 'meaning'])
    

    I am mainly interested in the meaning:

    j['meaning'].keys() # dict_keys(['adjective', 'noun', 'verb', 'adverb'])
    

    To get the pandas dataframe I used following code:

    json_normalize(data=j['meaning'])
    

    This gives a dataframe with only 4 columns.

    Here, each part of speech ( adjective, noun, etc) must have 'definition' key and 'example' and 'synonyms' are optional.

    j['meaning']['adjective'][0].keys() # dict_keys(['definition', 'example', 'synonyms'])
    

    How to get the dataframe with 4 * 3 = 12 columns, with column names like adjective_definition, adjective_example, ...., verb_synonyms?

    I tried to get some ideas from following links:

    http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.io.json.json_normalize.html
    https://www.kaggle.com/jboysen/quick-tutorial-flatten-nested-json-in-pandas/notebook
    pandas.io.json.json_normalize with very nested json

    But, could not solve the problem. Help will be appreciated.

  • BhishanPoudel
    BhishanPoudel over 5 years
    Thanks for the one-liner.