2013-07-19 21 views
7

Sono nuovo di panda e questa è la mia prima domanda su StackOverflow, sto cercando di fare qualche analisi con i panda.Creare un DataFrame panda da più dicts

Ho alcuni file di testo con i record di dati che voglio elaborare. Ogni riga del file corrisponde a un record quali campi si trovano in un punto fisso e hanno una lunghezza di un numero fisso di caratteri. Esistono diversi tipi di record sullo stesso file, tutti i record condividono il primo campo che è composto da due caratteri a seconda del tipo di record. Per fare un esempio:

Some file: 
01Jhon  Smith  555-1234           
03Cow   Bos primigenius taurus  00401     
01Jannette Jhonson   00100000000        
... 


field start length 
type   1  2 *common to all records, example: 01 = person, 03 = animal 
name   3  10 
surname  13  10 
phone  23  8 
credit  31  11 
fill of spaces 

Sto scrivendo un codice per convertire un record a un dizionario:

person1 = {'type': 01, 'name': = 'Jhon', 'surname': = 'Smith', 'phone': '555-1234'} 
person2 = {'type': 01, 'name': 'Jannette', 'surname': 'Jhonson', 'credit': 1000000.00} 
animal1 = {'type': 03, 'cname': 'cow', 'sciname': 'Bos....', 'legs': 4, 'tails': 1 } 

Se un campo è vuoto (riempito con gli spazi) non ci sarà nel dizionario) .

Con tutti i record di un tipo, voglio creare un DataFrame di panda con i tasti dicts come nome di colonna, ho provato con pandas.DataFrame.from_dict() senza successo.

E qui arriva la mia domanda: C'è un modo per farlo con i panda in modo che i tasti dict diventino nomi di colonne? Esistono altri metodi standard per gestire questo tipo di file?

risposta

7

Per effettuare una dataframe da un dizionario, è possibile passare un lista di dizionari:

>>> person1 = {'type': 01, 'name': 'Jhon', 'surname': 'Smith', 'phone': '555-1234'} 
>>> person2 = {'type': 01, 'name': 'Jannette', 'surname': 'Jhonson', 'credit': 1000000.00} 
>>> animal1 = {'type': 03, 'cname': 'cow', 'sciname': 'Bos....', 'legs': 4, 'tails': 1 } 
>>> pd.DataFrame([person1]) 
    name  phone surname type 
0 Jhon 555-1234 Smith  1 
>>> pd.DataFrame([person1, person2]) 
    credit  name  phone surname type 
0  NaN  Jhon 555-1234 Smith  1 
1 1000000 Jannette  NaN Jhonson  1 
>>> pd.DataFrame.from_dict([person1, person2]) 
    credit  name  phone surname type 
0  NaN  Jhon 555-1234 Smith  1 
1 1000000 Jannette  NaN Jhonson  1 

Per la questione più fondamentale di due file in modo diverso in formato mescolati, e assumendo che i file non sono così grande che non possiamo leggerli e memorizzarli nella memoria, io userei StringIO per creare un oggetto che è un po 'come un file ma che ha solo le linee che vogliamo, e quindi usare read_fwf (file a larghezza fissa) . Per esempio:

from StringIO import StringIO 

def get_filelike_object(filename, line_prefix): 
    s = StringIO() 
    with open(filename, "r") as fp: 
     for line in fp: 
      if line.startswith(line_prefix): 
       s.write(line) 
    s.seek(0) 
    return s 

e poi

>>> type01 = get_filelike_object("animal.dat", "01") 
>>> df = pd.read_fwf(type01, names="type name surname phone credit".split(), 
        widths=[2, 10, 10, 8, 11], header=None) 
>>> df 
    type  name surname  phone  credit 
0  1  Jhon Smith 555-1234  NaN 
1  1 Jannette Jhonson  NaN 100000000 

dovrebbe funzionare. Naturalmente è anche possibile separare i file in tipi diversi prima che li vedano mai pandas, il che potrebbe essere il più semplice di tutti.

+0

Grazie, la _list of_ dicts è la chiave. I file sono centinaia di Mz compressi con gzip e diversi GB non rappresentati, quindi leggeranno riga per riga e accodati al DataFrame corrispondente. – tinproject

Problemi correlati