Создание pandas данных из словаря словарей
У меня есть словарь словарей формы:
{'user':{movie:rating} }
Например,
{Jill': {'Avenger: Age of Ultron': 7.0,
'Django Unchained': 6.5,
'Gone Girl': 9.0,
'Kill the Messenger': 8.0}
'Toby': {'Avenger: Age of Ultron': 8.5,
'Django Unchained': 9.0,
'Zoolander': 2.0}}
Я хочу преобразовать этот dict dicts в фреймворк pandas со столбцом 1 имя пользователя и другие столбцы рейтинги фильмов i.e.
user Gone_Girl Horrible_Bosses_2 Django_Unchained Zoolander etc. \
Однако некоторые пользователи не оценивали фильмы и поэтому эти фильмы не включены в значения() для этого пользовательского ключа(). Было бы неплохо в этих случаях просто заполнить запись NaN.
На данный момент я перебираю ключи, заполняю список, а затем использую этот список для создания фрейма данных:
data=[]
for i,key in enumerate(movie_user_preferences.keys() ):
try:
data.append((key
,movie_user_preferences[key]['Gone Girl']
,movie_user_preferences[key]['Horrible Bosses 2']
,movie_user_preferences[key]['Django Unchained']
,movie_user_preferences[key]['Zoolander']
,movie_user_preferences[key]['Avenger: Age of Ultron']
,movie_user_preferences[key]['Kill the Messenger']))
# if no entry, skip
except:
pass
df=pd.DataFrame(data=data,columns=['user','Gone_Girl','Horrible_Bosses_2','Django_Unchained','Zoolander','Avenger_Age_of_Ultron','Kill_the_Messenger'])
Но это только дает мне фреймворк пользователей, которые оценили все фильмы в наборе.
Моя цель - добавить в список данных итерацию над метками фильма (вместо приведенного выше подхода к грубой силе) и, во-вторых, создать фрейм данных, который включает всех пользователей, и который помещает нулевые значения в элементы, которые не есть рейтинги фильмов.
Ответы
Ответ 1
Вы можете передать dict dict в конструктор DataFrame:
In [11]: d = {'Jill': {'Django Unchained': 6.5, 'Gone Girl': 9.0, 'Kill the Messenger': 8.0, 'Avenger: Age of Ultron': 7.0}, 'Toby': {'Django Unchained': 9.0, 'Zoolander': 2.0, 'Avenger: Age of Ultron': 8.5}}
In [12]: pd.DataFrame(d)
Out[12]:
Jill Toby
Avenger: Age of Ultron 7.0 8.5
Django Unchained 6.5 9.0
Gone Girl 9.0 NaN
Kill the Messenger 8.0 NaN
Zoolander NaN 2.0
Или используйте метод from_dict
:
In [13]: pd.DataFrame.from_dict(d)
Out[13]:
Jill Toby
Avenger: Age of Ultron 7.0 8.5
Django Unchained 6.5 9.0
Gone Girl 9.0 NaN
Kill the Messenger 8.0 NaN
Zoolander NaN 2.0
In [14]: pd.DataFrame.from_dict(d, orient='index')
Out[14]:
Django Unchained Gone Girl Kill the Messenger Avenger: Age of Ultron Zoolander
Jill 6.5 9 8 7.0 NaN
Toby 9.0 NaN NaN 8.5 2
Ответ 2
Этот подход с грубой силой также работает, но повторение над лейблами фильмов по-прежнему будет более надежным.
data=[]
for i,key in enumerate(movie_user_preferences.keys() ):
try:
data.append((key
,movie_user_preferences[key]['Gone Girl'] if 'Gone Girl' in movie_user_preferences[key] else 'NaN'
,movie_user_preferences[key]['Horrible Bosses 2'] if 'Horrible Bosses 2' in movie_user_preferences[key] else 'NaN'
,movie_user_preferences[key]['Django Unchained'] if 'Django Unchained' in movie_user_preferences[key] else 'NaN'
,movie_user_preferences[key]['Zoolander'] if 'Zoolander' in movie_user_preferences[key] else 'NaN'
,movie_user_preferences[key]['Avenger: Age of Ultron'] if 'Avenger: Age of Ultron' in movie_user_preferences[key] else 'NaN'
,movie_user_preferences[key]['Kill the Messenger'] if 'Kill the Messenger' in movie_user_preferences[key] else 'NaN' ))
# if no entry, skip
except:
pass
user Gone_Girl Horrible_Bosses_2 Django_Unchained Zoolander \
0 Sam 6 3 7.5 7
1 Max 10 6 7.0 10
2 Robert NaN 5 7.0 9
3 Toby NaN NaN 9.0 2
4 Julia 6.5 NaN 6.0 6.5
5 William 7 4 8.0 4
6 Jill 9 NaN 6.5 NaN
Avenger_Age_of_Ultron Kill_the_Messenger
0 10.0 5.5
1 7.0 5
2 8.0 9
3 8.5 NaN
4 10.0 6
5 6.0 6.5
6 7.0 8