I have a nested dictionary as below:
JavaScript
x
13
13
1
stud_data_dict = { 's1' : {'Course 1' : {'Course Name':'Maths',
2
'Marks':95,
3
'Grade': 'A+'},
4
'Course 2' : {'Course Name':'Science',
5
'Marks': 75,
6
'Grade': 'B-'}},
7
's2' : {'Course 1' : {'Course Name':'English',
8
'Marks': 82,
9
'Grade': 'B'},
10
'Course 2' : {'Course Name':'Maths',
11
'Marks': 90,
12
'Grade': 'A'}}}
13
I need to convert it into a dataframe like below
JavaScript
1
5
1
Student Course 1 Course 2
2
Course Name Marks Grade Course Name Marks Grade
3
s1 Maths 95 A+ Science 75 B-
4
s2 English 82 B Maths 90 A
5
I have tired the following code from this answer
JavaScript
1
3
1
stud_df = pandas.DataFrame.from_dict(stud_data_dict, orient="index").stack().to_frame()
2
final_df = pandas.DataFrame(stud_df[0].values.tolist(), index=stud_df.index)
3
I am getting the dataframe like below
JavaScript
1
6
1
Course Name Marks Grade
2
s1 Course 1 Maths 95 A+
3
Course 2 Science 75 B-
4
s2 Course 1 English 82 B
5
Course 2 Maths 90 A
6
This is the closest I got to the desired output. What changes do I need to make to the code to get the desired dataframe?
Advertisement
Answer
Change dictionary
first and then pass to Series
with reshape by Series.unstack
:
JavaScript
1
14
14
1
#reformat nested dict
2
#https://stackoverflow.com/a/39807565/2901002
3
d = {(level1_key, level2_key, level3_key): values
4
for level1_key, level2_dict in stud_data_dict.items()
5
for level2_key, level3_dict in level2_dict.items()
6
for level3_key, values in level3_dict.items()}
7
8
stud_df = pd.Series(d).unstack([1,2])
9
print (stud_df)
10
Course 1 Course 2
11
Course Name Marks Grade Course Name Marks Grade
12
s1 Maths 95 A+ Science 75 B-
13
s2 English 82 B Maths 90 A
14
Another idea is created dictionary of tuples in keys with defaultdict
:
JavaScript
1
16
16
1
from collections import defaultdict
2
3
d = defaultdict(dict)
4
5
for k, v in stud_data_dict.items():
6
for k1, v1 in v.items():
7
for k2, v2 in v1.items():
8
d[(k1, k2)].update({k: v2})
9
10
df = pd.DataFrame(d)
11
print(df)
12
Course 1 Course 2
13
Course Name Marks Grade Course Name Marks Grade
14
s1 Maths 95 A+ Science 75 B-
15
s2 English 82 B Maths 90 A
16