Miranda Miranda -5 years ago 191
Python Question

Pandas: Import feature vectors from list of dictionaries into dataframe

I have a list of dictionaries, and each dictionary consists of two key-value tuples. The first key-value is the name of a person and the second one is a feature vector consisting of the grades each person achieved in different courses. For example:

ListOfGrades=[{'Name':"Mike", 'grades':[98,86,90,72]},{'Name':"Sasha", 'grades':[92,79,85,94]},{'Name':"Beth", 'grades':[89,89,76,90]}]

I want to import this data into a pandas dataframe such that each row has the label of a person's name with each column filled with their grades. In short, I need to get something like this:

Mike 98 86 90 72
Sasha 92 79 85 94
Beth 89 89 76 90

I know I should use pd.DataFrame(ListOfGrades), but I'm not sure how to set it for my purpose. I have seen Convert list of dictionaries to Dataframe, but it's different from the way I want to order my data in the data frame.
I have tried this:

for i in ListOfGrades:

# Convert to dataframe
df = pd.DataFrame.from_dict(ListOfGrades, orient='index').reset_index()

But, python throws me an error:

TypeError: list indices must be integers, not dict

Also, I don't know how to add the names to each row, such that the first column of my data frame consists of the name of people, like the way I want my data frame look (as I showed above). Any help is appreciated!

Answer Source

Ok, this approach is a bit of a hack, and it will quickly run into problems if each student doesn't have the same number of grades, but essentially, you need to build a new list and create the dictionary from that list. For python 3.5:

new_list = []
for student in ListOfGrades:
    new_list.append({'Name': student['Name'], **{'grade_'+str(i+1): grade for i, grade in enumerate(student['grades'])}})

df = pd.DataFrame(new_list)

This is the dataframe I'm getting:

    Name  grade_1  grade_2  grade_3  grade_4
0   Mike       98       86       90       72
1  Sasha       92       79       85       94
2   Beth       89       89       76       90

If you don't have python 3.5 but have a version of python 3, this should work:

new_list = []
for student in ListOfGrades:
    new_list.append(dict(Name = student['Name'], **{'grade_'+str(i+1): grade for i, grade in enumerate(student['grades'])}))

df = pd.DataFrame(new_list)

Edited to add: The above should also work for python 2.7

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download