#python #python-3.x #pandas #dictionary
#python #python-3.x #pandas #словарь
Вопрос:
У меня есть этот вложенный словарь:
{'attrs': ('LA', 'E', 'Can', 'AP', 'ME', 'A', 'M', 'Car', 'US'),
'self': {'ac': {'AP', 'Can', 'Car', 'E', 'LA', 'M', 'ME', 'US'},
'anz': {'AP', 'E', 'US'},
'ana': {'AP', 'E', 'US'},
'aa': {'AP'},
'taag': {'A', 'AP', 'Can', 'E', 'ME', 'US'},
'bm': {'E'},
'l': {'A', 'AP', 'Can', 'E', 'LA', 'M', 'ME', 'US'},
'm': {'Can', 'Car', 'LA', 'M', 'US'},
'sca': {'A', 'AP', 'E', 'LA', 'US'},
'sia': {'A', 'AP', 'Can', 'E', 'ME', 'US'},
'tai': {'AP', 'Car', 'E', 'LA', 'US'},
'ua': {'AP', 'Can', 'Car', 'E', 'LA', 'M', 'US'},
'v': {'A', 'AP', 'E', 'LA', 'M', 'US'}}}
Вот как я его создаю:
build_context = lambda objects, attributes, table : {'attrs' : tuple(attributes), 'self' : {object : {attributes[i] for i in range(len(row)) if row[i]} for (object, row) in zip(objects, table)}}
context = build_context(objects =
('ac', 'anz', 'ana', 'aa', 'taag', 'bm', 'l', 'm', 'sca', 'sia', 'tai',
'ua', 'v'),
attributes = ('LA', 'E', 'Can', 'AP', 'ME', 'A', 'M', 'Car', 'US'),
table = ((True,True,True,True,True,False,True,True,True),
(False,True,False,True,False,False,False,False,True), (False,True,False,True,False,False,False,False,True),
(False,False,False,True,False,False,False,False,False),
(False,True,True,True,True,True,False,False,True),
(False,True,False,False,False,False,False,False,False),
(True,True,True,True,True,True,True,False,True),
(True,False,True,False,False,False,True,True,True), (True,True,False,True,False,True,False,False,True),
(False,True,True,True,True,True,False,False,True),
(True,True,False,True,False,False,False,True,True),
(True,True,True,True,False,False,True,True,True),
(True,True,False,True,False,True,True,False,True)))
Как превратить его в фрейм данных pandas? Это должно выглядеть так, но я использовал сокращения в своем коде:
Комментарии:
1. пожалуйста, укажите ожидаемый формат вывода
2. Можете ли вы предоставить некоторый образец ожидаемого вывода / фрейма данных?
3. @anon01 да, я добавил его
4. @IoaTzimas да, я добавил его
Ответ №1:
Давайте попробуем explode
тогда crosstab
s = pd.Series(d['self']).apply(list).explode()
out = pd.crosstab(s.index,s).reindex(columns=d['attrs'],fill_value=0)
out =out.rename_axis(None).rename_axis(None,axis=1).reset_index().rename(columns={'index':'company'})
Out[193]:
company LA E Can AP ME A M Car US
0 aa 0 0 0 1 0 0 0 0 0
1 ac 1 1 1 1 1 0 1 1 1
2 ana 0 1 0 1 0 0 0 0 1
3 anz 0 1 0 1 0 0 0 0 1
4 bm 0 1 0 0 0 0 0 0 0
5 l 1 1 1 1 1 1 1 0 1
6 m 1 0 1 0 0 0 1 1 1
7 sca 1 1 0 1 0 1 0 0 1
8 sia 0 1 1 1 1 1 0 0 1
9 taag 0 1 1 1 1 1 0 0 1
10 tai 1 1 0 1 0 0 0 1 1
11 ua 1 1 1 1 0 0 1 1 1
12 v 1 1 0 1 0 1 1 0 1
Комментарии:
1. спасибо, а что такое row_0? его там не должно быть
2. можно ли также удалить row_0 и создать столбец col_0? так что я могу разобрать [«col_0»], например
3. @french_fries row_0 — это имя индекса, а col_0 — имя столбца, это ни на что не повлияет
4. aa, ac, ana, …. должны быть значениями в столбце, а не индексом. как в примере. в примере столбец имеет имя «company»
Ответ №2:
Вот мое решение:
attributes = ('LA', 'E', 'Can', 'AP', 'ME', 'A', 'M', 'Car', 'US')
data=d['self']
new_data=[]
for i in data:
l={}
for k in attributes:
if k in data[i]:
l[k]=1
else:
l[k]=0
new_data.append(l)
res=pd.DataFrame_from_dict(new_data, orient='columns')
res['company']=data.keys()
res=res[['company', 'LA', 'E', 'Can', 'AP', 'ME', 'A', 'M', 'Car', 'US']]
print(res)
Вывод:
company LA E Can AP ME A M Car US
0 ac 1 1 1 1 1 0 1 1 1
1 anz 0 1 0 1 0 0 0 0 1
2 ana 0 1 0 1 0 0 0 0 1
3 aa 0 0 0 1 0 0 0 0 0
4 taag 0 1 1 1 1 1 0 0 1
5 bm 0 1 0 0 0 0 0 0 0
6 l 1 1 1 1 1 1 1 0 1
7 m 1 0 1 0 0 0 1 1 1
8 sca 1 1 0 1 0 1 0 0 1
9 sia 0 1 1 1 1 1 0 0 1
10 tai 1 1 0 1 0 0 0 1 1
11 ua 1 1 1 1 0 0 1 1 1
12 v 1 1 0 1 0 1 1 0 1
Комментарии:
1. aa, ac, ana, …. должны быть значениями в столбце, а не индексом. как в примере. в примере столбец имеет имя «company»
2. Обновлено, пожалуйста, проверьте еще раз