Как превратить вложенный словарь в фрейм данных pandas?

#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. Обновлено, пожалуйста, проверьте еще раз