I currently have a Python script which uses a flatten function in order to flatten a JSON object, which I will then use json_normalize to turn the flattened JSON into a DataFrame.
import pandas as pd
from pandas import json_normalize
from collections.abc import MutableMapping as mm
def flatten(dictionary, p_key=None, parent_key=False, separator='.'):
items = []
if isinstance(dictionary, list):
for listval in dictionary:
items.extend(flatten(listval).items())
return dict(items)
for key, value in dictionary.items():
if parent_key:
new_key = f"{str(p_key)}{separator}{key}"
else:
new_key = p_key if p_key else key
if isinstance(value, mm):
items.extend(flatten(
dictionary=value,
p_key=new_key,
parent_key=True,
separator=separator).items())
elif isinstance(value, list):
for k, v in enumerate(value):
items.extend(flatten(
dictionary={str(k): v},
p_key=new_key,
parent_key=False,
separator=separator).items())
else:
items.append((new_key, value))
return dict(items)
jfile = [{
"id" : 1,
"labelId" : 169,
"indicators" : [
62
],
"Wait" : 6,
"Levels" : [
{
"isActive" : "true",
"pressure" : 3,
"actions" : [
{
"isActive" : "true",
"description" : "Place"
}
],
"users" : [
5467,
5469,
5
]
},
{
"isActive" : "true",
"pressure" : 2,
"actions" : [
{
"isActive" : "true",
"description" : "Test"
}
],
"users" : [
3253,
6903
]
}
]
}]
flatdoc = [flatten(i) for i in jfile]
flatdoc = json_normalize(flatdoc)
print(flatdoc)
Current Output:
id labelId indicators Wait Levels.isActive Levels.pressure Levels.actions.isActive Levels.actions.description Levels.users
1 169 62 6 true 2 true Test 6903
The output I'm currently getting is retrieving the last value from the last key that is found in the JSON object for some reason. What I need it to do is retrieve it from the first key within the dictionary and then when that list is not nested and just contains numbers/integers it should simply explode it so the result can look like the below:
Expected Output:
id labelId indicators Wait Levels.isActive Levels.pressure Levels.actions.isActive Levels.actions.description Levels.users
1 169 62 6 true 3 true Place 5467
1 169 62 6 true 3 true Place 5469
1 169 62 6 true 3 true Place 5
How would I go about amending the function so that it locates the correct key to produce the appropriate value?