2009-10-07 7 views
11

Mam serię dużych plików tekstowych (do 1 gigabajta), które pochodzą z eksperymentu, który należy przeanalizować w języku Python. Oni najlepiej załadowane do 2D numpy tablicy, która przedstawia pierwsze pytanie:Przyrostowe budowanie tablicy numpy i mierzenie użycia pamięci

  • Ponieważ liczba wierszy jest znana na początku załadunku, w jaki sposób bardzo duża numpy array być najefektywniej zbudowana, rząd po rzędzie?

Po prostu dodanie rzędu do tablicy byłoby nieefektywne pod względem pamięci, ponieważ dwie duże tablice chwilowo współistnieją. Ten sam problem wydaje się występować, jeśli używasz numpy.append. Funkcje stack są obiecujące, ale najlepiej chciałbym rozbudować macierz na miejscu.

Prowadzi to do drugiego pytania:

  • Jaki jest najlepszy sposób, aby obserwować zużycie pamięci programu Pythona, który mocno używa numpy tablice?

Aby zbadać powyższy problem, użyłem zwykłych narzędzi do profilowania pamięci - heapy i pympler - ale otrzymuję tylko rozmiar zewnętrznych obiektów tablicy (80 bajtów), a nie dane, które zawierają. Poza prostym pomiarem, ile pamięci wykorzystuje proces Pythona, jak mogę uzyskać "pełny" rozmiar tablic w miarę ich wzrostu?

Dane lokalne: OSX 10.6, Python 2.6, ale ogólne rozwiązania są mile widziane.

Odpowiedz

7

Nie można zagwarantować, że macie możliwość rozbudowania macierzy w miejsce innym niż utworzenie pustej tablicy (numpy.empty) o maksymalnym możliwym rozmiarze, a następnie użycie tego widoku na końcu. Nie możesz zacząć od małej, ponieważ nie ma gwarancji, że możesz rozszerzyć dowolną pamięć na mapie, nie przekręcając innych danych. (A wszystko to jest o wiele niższy poziom niż python pozwala uzyskać z wnętrza tłumacza.)

Twój najlepszy zakład to prawdopodobnie numpy.fromiter. Patrząc na źródło, gdy liczba przedmiotów rośnie, tablica jest powiększana o nieco ponad 50% za każdym razem. Jeśli możesz łatwo uzyskać liczbę wierszy (np. Od zliczania linii), możesz nawet przekazać jej liczbę.

1

Możliwe jest wykonanie pojedynczego przejścia przez plik, aby zliczyć liczbę rzędów bez ich ładowania.

Inną opcją jest podwoić swoją wielkość stołu za każdym razem, który ma dwie zalety:

  1. będzie tylko pamięć dziennika ponownie Alloc (n) razy, gdzie n jest liczbą wierszy.
  2. Trzeba tylko 50% więcej pamięci RAM niż największy rozmiar tabeli

Zażycie dynamiczną trasę, można zmierzyć długość pierwszego rzędu w bajtach, a następnie odgadnąć liczbę wierszy przez obliczenie (num bajty w pliku/liczba bajtów w pierwszym wierszu). Zacznij od tabeli o tym rozmiarze.

+0

Dzięki wszystkim. Biorąc pod uwagę rozmiar pliku, byłem niechętny do zrobienia wstępnego podania tylko po to, by policzyć linie, ale wydaje się to najłatwiejszym i najbardziej efektywnym sposobem rozwiązania problemu z pamięcią. –

+1

Wcześniej zadałem podobne pytanie temu pracownikowi i wpadłem na inną możliwość, która mogłaby cię uratować od wstępnej przepustki. Jeśli znasz przybliżony rozmiar "elementu" w pliku, możesz podzielić go na rozmiar pliku. Dodaj trochę wyściółki dla bezpieczeństwa, a następnie możesz napisać do całej pamięci. Aby ukryć dodatkowe, niezainicjowane, możesz użyć widoku tylko elementów z danymi. Musisz się upewnić, że się nie przejdziesz. Nie jest doskonały, ale jeśli twoje pliki czytają są wolne, a twoje dane są konsekwentnie rozłożone, może to zadziałać. – AFoglia

2

Czy próbowałeś używać pliku memmap? Możesz iterować przez plik wejściowy (w miarę możliwości) i konwertować przychodzące dane i wstawiać je jako wiersze do tablicy nump odwzorowanej w pamięci. Wadą jest ponoszenie większej ilości dysków i/o w przypadku niewystarczającej pamięci głównej i konieczne staje się stronicowanie z zamiany.

Patrz: http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html

Inną alternatywą jest PyTables. Musisz skonstruować specjalny tabel podobny do sql, ale jest to dość proste. W rzeczywistości zapewnia przezroczystą trwałość dysku (automatyczną serializację) i hierarchiczną organizację danych. Ogranicza to również ilość wykorzystanej pamięci głównej.

Patrz: www.pytables.org/moin/HowToUse

Powodzenia!

0

Problem jest w istocie plikiem tekstowym. Kiedy twoje dane wejściowe są przechowywane w bardziej zaawansowanych, można uniknąć takich problemów. Weźmy na przykład spojrzenie na h5py project. Warto najpierw przekonwertować dane na pliki HDF5, a następnie uruchomić skrypty analityczne na plikach HDF5.