2013-07-19 10 views
7

Jestem nowy w pandach i to jest moje pierwsze pytanie na stackoverflow, próbuję zrobić kilka analiz z pandami.Tworzenie pandy DataFrame z wielu dyktafonów

Mam kilka plików tekstowych z rekordami danych, które chcę przetworzyć. Każda linia pliku odpowiada rekordowi, które pola są w stałym miejscu i mają długość ustalonej liczby znaków. Istnieją różne rodzaje rekordów w tym samym pliku, wszystkie rekordy dzielą pierwsze pole, które są dwoma znakami w zależności od typu rekordu. Jako przykład:

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 

Piszę niektóre kodu do konwersji jednego rekordu do słownika:

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 } 

Jeśli pole jest puste (wypełnione spacjami) tam nie będzie w słowniku) .

Ze wszystkimi rekordami jednego rodzaju chcę utworzyć pandas DataFrame z kluczami dyktowanymi jako nazwami kolumn, spróbuj z pandas.DataFrame.from_dict() bez powodzenia.

I tu pojawia się moje pytanie: czy można to zrobić z pandami, więc klucze dyktowane stają się nazwami kolumn? Czy jest jakaś inna standardowa metoda radzenia sobie z tego rodzaju plikami?

Odpowiedz

7

Aby DataFrame ze słownikiem, można zdać listy słowników:

>>> 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 

Dla bardziej fundamentalnej kwestii dwóch różnie sformatowanych plików przemieszane, a zakładając, że pliki nie są tak duże, że nie możemy ich odczytać i przechowywać w pamięci, użyłbym StringIO do utworzenia obiektu, który jest czymś w rodzaju pliku, ale który ma tylko wiersze, które chcemy, a następnie użyć read_fwf (plik o stałej szerokości) . Na przykład:

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 

a następnie

>>> 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 

powinno działać. Oczywiście można również rozdzielić pliki na różne typy, zanim je zobaczy, co może być najłatwiejsze.

+0

Dziękuję, _list of_ dicts jest kluczem. Pliki są setkami skompresowanego gbip Mbs i nieskompresowanych Gb, więc odczyta się wiersz po linii i dołącza do odpowiedniej ramki DataFrame. – tinproject