2016-01-27 2 views
0

На немного потери, несмотря на много поиска & экспериментирования ... Учитывая это:преобразование списков однородных dicts в панд Dataframe с вложенной dicts как мультииндекс

dictA = {'order': '1', 
     'char': {'glyph': 'A', 
        'case': 'upper', 
        'vowel': True} 
     } 
dictB = {'order': '2', 
     'char': {'glyph': 'B', 
        'case': 'upper', 
        'vowel': False} 
     } 
dictC = {'order': '3', 
     'char': {'glyph': 'C', 
        'case': 'upper', 
        'vowel': False} 
     } 
dictD = {'order': '4', 
     'char': {'glyph': 'd', 
        'case': 'lower', 
        'vowel': False} 
     } 
dictE = {'order': '5', 
     'char': {'glyph': 'e', 
        'case': 'lower', 
        'vowel': True} 
     } 
letters = [dictA, dictB, dictC, dictD, dictE] 

как превратить letters в в этом: (первый столбец индекса)

order    char 
      glyph  case  vowel 
0  1  A  upper  True 
1  2  B  upper  False 
2  3  C  upper  False 
3  4  d  lower  False 
4  5  e  lower  True 

... и как плюс, а затем иметь возможность работать на этом кадре подсчитывать/участка количество записей в верхнем регистре, количество записей, которые являются гласными, и т. д.

Любые идеи?

EDIT: Мой первоначальный пример был, возможно, слишком простым, но я оставлю его для потомков.

Дано:

import re 

class Glyph(dict): 

    def __init__(self, glyph): 
     super(Glyph, self).__init__() 
     order = ord(glyph) 
     self['glyph'] = glyph 
     self['order'] = order 
     kind = {'type': None} 
     if re.search('\s+', glyph): 
      kind = {'type': 'whitespace'} 

     elif order in (range(ord('a'), ord('z')) + 
         range(ord('A'), ord('Z')) 
         ): 

      lowercase = glyph.lower() 
      kind = { 
       'type': lowercase, 
       'vowel': lowercase in ['a', 'e', 'i', 'o', 'u'], 
       'case': ['upper', 'lower'][lowercase == glyph], 
       'number': (ord(lowercase) - ord('a') + 1) 
      } 
     self['kind'] = kind 

chars = [Glyph(x) for x in 'Hello World'] 

Я могу это сделать:

import pandas as pd 
df = pd.DataFrame(chars) # dataframe where 'order' & 'glyph' are OK... 
# unpack 'kind' Series into list of dicts and use those to make a table 
kindDf = pd.DataFrame(data=[x for x in df['kind']]) 

Моя интуиция приведет меня думать, что я мог бы сделать это:

df['kind'] = kindDf 

... Но добавляет только первый столбец моего kindDF и помещает его под «kind» в df. Следующая попытка:

df.pop('kind') # get rid of this column of dicts 
joined = df.join(kindDf) # flattens 'kind'... 

joined является так близко! Проблема в том, что я хочу, чтобы эти столбцы были видны под «доброй» иерархией, а не плоской (как результат joined). Я попробовал стек/матку, но я не могу это понять. Нужен ли мне MultiIndex?

ответ

1

Это заставляет вас закрыть на первой части:

## a list for storing properly formated dataframes 
container=[] 
for l in letters: 

    ## loop through list of dicts, turn each into a dataframe 
    ## then add `order` to the index. Then make the dataframe wide using unstack 
    temp = pd.DataFrame(data=l).set_index('order',append=True).unstack(level=[0]) 
    container.append(temp) 

## throw all the dataframes together into one 
result = pd.concat(container).reset_index() 
result 

    order char    
      case glyph vowel 
0  1 upper  A True 
1  2 upper  B False 
2  3 upper  C False 
3  4 lower  d False 
4  5 lower  e True 

Для второй части, вы можете полагаться только на groupby, а затем встроенный в построении функции для быстрого визуалов. Опустите plot звонок после size(), если вы просто хотите увидеть счет.

result.groupby(result.char.vowel).size().plot(kind='bar', 
     figsize=[8,6]) 
title('Glyphs are awesome') 

enter image description here

+0

Это еще Wizardry для меня, но я предполагаю, что я получил результаты, которые я просил. По-прежнему возникают проблемы с пониманием того, как перефразировать столбец dicts. –

+0

@RyandeKleer Я добавил несколько комментариев к коду. Я часто использую индексирование и отламывание для реструктуризации данных в целом. – ako

+0

@RyandeKleer, были ли какие-либо последующие вопросы или это было решено для вас? – ako

Смежные вопросы