Obecnie próbuję otworzyć plik z pandami i pytonem do celów uczenia maszynowego, idealnie byłoby dla mnie mieć je wszystkie w ramce danych. Teraz plik ma 18 GB, a moja pamięć RAM to 32 GB, ale wciąż pojawiają się błędy pamięci.
Czy z twojego doświadczenia jest to możliwe? Jeśli nie, czy znasz lepszy sposób na obejście tego? (Tabela gałęzi? Zwiększ rozmiar mojej pamięci RAM do 64? Utwórz bazę danych i uzyskaj do niej dostęp z Pythona)
pandas
, że musisz mieć 5-10 razy więcej pamięci RAM. Polecam wykonywanieinplace
operacji, jawne wywołanie wgarbage.collector
celu cofnięcia alokacji obiektów.Odpowiedzi:
Jeśli jest to plik csv i nie musisz uzyskiwać dostępu do wszystkich danych jednocześnie podczas szkolenia algorytmu, możesz odczytać go we fragmentach. Ta
pandas.read_csv
metoda umożliwia odczytanie pliku w takich fragmentach:Oto dokumentacja metody
źródło
Istnieją dwie możliwości: albo musisz mieć wszystkie dane w pamięci do przetwarzania (np. Algorytm uczenia maszynowego będzie chciał zużyć wszystkie z nich naraz), albo możesz się bez niego obejść (np. Twój algorytm potrzebuje tylko próbek wierszy lub kolumny jednocześnie).
W pierwszym przypadku musisz rozwiązać problem z pamięcią . Zwiększ rozmiar pamięci, wynajmij maszynę chmurową o wysokiej pamięci, używaj operacji wewnętrznych, dostarczaj informacji o typie danych, które czytasz, pamiętaj o usunięciu wszystkich nieużywanych zmiennych i zbieraniu śmieci itp
Jest bardzo prawdopodobne, że 32 GB pamięci RAM nie wystarczy, aby Pandas mógł obsłużyć twoje dane. Zauważ, że liczba całkowita „1” jest tylko jednym bajtem, gdy jest zapisana jako tekst, ale 8 bajtów, gdy jest reprezentowana jako
int64
(co jest wartością domyślną, gdy Pandas odczytuje ją z tekstu). Możesz zrobić ten sam przykład z liczbą zmiennoprzecinkową „1.0”, którafloat64
domyślnie rozszerza się z ciągu 3-bajtowego na 8-bajtowy . Możesz zyskać trochę miejsca, informując Pandy dokładnie, jakich typów użyć dla każdej kolumny i wymuszając najmniejsze możliwe reprezentacje, ale nie zaczęliśmy nawet mówić o strukturze danych Pythona tutaj, co może dodać dodatkowy wskaźnik lub dwa tutaj lub tam łatwo , a wskaźniki mają po 8 bajtów na komputerze 64-bitowym.Podsumowując: nie, 32 GB pamięci RAM prawdopodobnie nie wystarcza, aby Pandas mógł obsłużyć plik 20 GB.
W drugim przypadku (który jest bardziej realistyczny i prawdopodobnie dotyczy Ciebie) musisz rozwiązać problem z zarządzaniem danymi . Rzeczywiście, konieczność załadowania wszystkich danych, gdy naprawdę potrzebujesz tylko ich części do przetwarzania, może być oznaką złego zarządzania danymi. Tutaj jest wiele opcji:
Użyj bazy danych SQL. Jeśli możesz, to prawie zawsze jest to pierwszy wybór i całkiem wygodne rozwiązanie. 20 GB wydaje się wielkością, z którą większość baz danych SQL poradziłaby sobie dobrze bez potrzeby dystrybucji nawet na (wyższej klasy) laptopie. Będziesz mógł indeksować kolumny, wykonywać podstawowe agregacje za pomocą SQL i pobierać potrzebne podpróbki do Pand w celu bardziej skomplikowanego przetwarzania za pomocą prostego
pd.read_sql
. Przeniesienie danych do bazy danych da również możliwość zastanowienia się nad faktycznymi typami danych i rozmiarami kolumn.Jeśli twoje dane są głównie numeryczne (tj. Tablice lub tensory), możesz rozważyć trzymanie ich w formacie HDF5 (patrz PyTables ), który pozwala wygodnie odczytywać tylko niezbędne fragmenty wielkich tablic z dysku. Podstawowe numpy.save i numpy.load osiągają ten sam efekt również poprzez mapowanie pamięci tablic na dysku. Dla GIS i powiązanych danych rastrowych istnieją dedykowane bazy danych , które mogą nie łączyć się z pandami tak bezpośrednio jak SQL, ale powinny również umożliwiać wygodne wykonywanie wycinków i zapytań.
O ile mi wiadomo, Pandy nie obsługują takiego „częściowego” mapowania pamięci HDF5 lub tablic numpy. Jeśli nadal chcesz mieć rozwiązanie typu „czysta panda”, możesz spróbować obejść ten problem poprzez „dzielenie”: albo przechowując kolumny dużego stołu osobno (np. W osobnych plikach lub w osobnych „tabelach” pojedynczego HDF5 plik) i ładowanie tylko niezbędnych na żądanie lub osobne przechowywanie fragmentów wierszy . Będziesz jednak musiał zaimplementować logikę ładowania niezbędnych fragmentów, a tym samym wynaleźć na nowo rowery już wdrożone w większości baz danych SQL, więc być może opcja 1 byłaby jeszcze łatwiejsza. Jeśli jednak dane są dostarczane w pliku CSV, można je przetwarzać na części, określając
chunksize
parametr napd.read_csv
.źródło
Właśnie miałem ten problem kilka dni temu! Nie jestem pewien, czy to pomaga w konkretnym przypadku, ponieważ nie podajesz tak wielu szczegółów, ale moja sytuacja polegała na pracy w trybie offline na „dużym” zestawie danych. Dane uzyskano jako pliki CSV w formacie 20z gzip z liczników energii, dane szeregów czasowych w odstępach kilku sekund.
Plik IO:
Utwórz iterator porcji bezpośrednio nad plikiem gzip (nie rozpakowuj!)
Iteruj po kawałkach
Wewnątrz pętli porcji filtruję i próbkuję na czas. W ten sposób zmniejszyłem rozmiar z 20 GB do kilkuset MB HDF5 do dalszej eksploracji danych offline.
źródło
Z mojego doświadczenia wynika, że inicjowanie za
read_csv()
pomocą parametrulow_memory=False
zwykle pomaga podczas czytania dużych plików. Nie sądzę, żebyś wspomniał o typie pliku, który czytasz, więc nie jestem pewien, czy ma to zastosowanie do twojej sytuacji.źródło
Jeśli Twój plik to CSV, możesz po prostu zrobić to w Chunk by Chunk. Możesz po prostu zrobić:
źródło