2012-04-22 40 views
9

złapałem Track1 zestawu danych KDD z Kaggle i postanowił załadować ~ 2,5 GB 3-kolumny pliku CSV do pamięci, 16 GB na moim instancji EC2 wysokiej Pamięć:poważne problemy z pamięcią czytanie w pliku csv przy użyciu numpy

data = np.loadtxt('rec_log_train.txt') 

sesja Pythona wyczerpała całą moją pamięć (100%), a następnie została zabita.

Potem czytałem ten sam plik używając R (via read.table) i użyłem mniej niż 5 GB pamięci RAM, który zwinął się do mniej niż 2 GB po tym, jak zadzwoniłem do garbage collectora.

Moje pytanie brzmi: dlaczego to się nie powiodło pod numpy i jaki jest właściwy sposób odczytu pliku do pamięci. Tak, mogę używać generatorów i unikać problemu, ale to nie jest celem.

+0

powiązane http://stackoverflow.com/questions/8956832/python-out-of-memory-on-large-csv-file-numpy – Anycorn

+0

Jeśli zrobi się pojedyncza precyzja, 'np.fromfile/np.loadtxt (dtype) = np.float32) 'zajmie mniej pamięci, następnie' X = X.astype (np.float64) 'po zakończeniu. – denis

Odpowiedz

6
import pandas, re, numpy as np 

def load_file(filename, num_cols, delimiter='\t'): 
    data = None 
    try: 
     data = np.load(filename + '.npy') 
    except: 
     splitter = re.compile(delimiter) 

     def items(infile): 
      for line in infile: 
       for item in splitter.split(line): 
        yield item 

     with open(filename, 'r') as infile: 
      data = np.fromiter(items(infile), float64, -1) 
      data = data.reshape((-1, num_cols)) 
      np.save(filename, data) 

    return pandas.DataFrame(data) 

to czyta w pliku 2,5 GB, a serializuje macierz wyjściową. Plik wejściowy jest odczytywany "leniwie", więc nie są budowane pośrednie struktury danych i używana jest minimalna ilość pamięci. Początkowe ładowanie trwa długo, ale każde kolejne obciążenie (zserializowanego pliku) jest szybkie. Proszę, daj mi, jeśli masz wskazówki!

+1

Jeśli podajesz liczbę kolumn a priori, dlaczego nie zrobić czegoś takiego jak to: https://gist.github.com/2465280? Na marginesie, aby utworzyć tablicę z generatora, użyj 'np.fromiter'. –

+0

zaktualizowana! Dziękuję bardzo! – vgoklani

Powiązane problemy