Próbuję odczytać duży plik csv (około 6 GB) w pandach i pojawia się błąd pamięci:
MemoryError Traceback (most recent call last)
<ipython-input-58-67a72687871b> in <module>()
----> 1 data=pd.read_csv('aphro.csv',sep=';')
...
MemoryError:
Jakaś pomoc na ten temat?
Odpowiedzi:
Błąd pokazuje, że komputer nie ma wystarczającej ilości pamięci, aby odczytać cały plik CSV do DataFrame jednocześnie. Zakładając, że nie potrzebujesz całego zestawu danych w pamięci jednocześnie, jednym ze sposobów uniknięcia problemu byłoby przetworzenie pliku CSV we fragmenty (poprzez określenie
chunksize
parametru):Ten
chunksize
parametr określa liczbę wierszy na porcję. (Ostatni fragment możechunksize
oczywiście zawierać mniej niż wiersze).źródło
DF.append(chunk)
wewnątrz pętli. To wykorzystaO(N^2)
operacje kopiowania. Lepiej jest dołączyć zagregowane dane do listy , a następnie zbudować DataFrame z listy za pomocą jednego wywołania dopd.DataFrame
lubpd.concat
(w zależności od rodzaju zagregowanych danych).DF.append(chunk)
w pętli wymagaO(N^2)
operacji kopiowania, gdzieN
jest wielkość porcji, ponieważ każde wywołanieDF.append
zwraca nową ramkę danych. Wywołaniepd.DataFrame
lubpd.concat
wyjście poza pętlę zmniejsza ilość kopii doO(N)
.chunksize
parametr odnosi się do liczby wierszy na porcję. Ostatni fragment możechunksize
oczywiście zawierać mniej niż wiersze.pd.concat([list_of_dfs])
raz po pętli jest znacznie szybsze niż dzwonieniepd.concat
lubdf.append
wiele razy w pętli. Oczywiście potrzebujesz znacznej ilości pamięci, aby pomieścić całe 6 GB csv jako jedną ramkę DataFrame.Tworzenie porcji nie zawsze powinno być pierwszym punktem wyjścia dla tego problemu.
Czy plik jest duży z powodu powtarzających się danych nienumerycznych lub niechcianych kolumn?
Jeśli tak, czasami możesz zobaczyć ogromne oszczędności pamięci, czytając kolumny jako kategorie i wybierając wymagane kolumny za pomocą
usecols
parametru pd.read_csv .Czy Twój przepływ pracy wymaga krojenia, manipulacji, eksportowania?
Jeśli tak, możesz użyć dask.dataframe do wycinania, wykonywania obliczeń i eksportowania iteracyjnego. Tworzenie porcji odbywa się w trybie cichym przez dask, który obsługuje również podzbiór API pand.
Jeśli wszystko inne zawiedzie, przeczytaj wiersz po wierszu za pomocą porcji.
Kawałek za pośrednictwem pand lub biblioteki csv w ostateczności.
źródło
Postępowałem tak:
źródło
read_csv
naread_table
?W przypadku dużych danych zalecam użycie biblioteki „dask”
np .:
Możesz przeczytać więcej z dokumentacji tutaj .
Inną świetną alternatywą byłoby użycie modiny, ponieważ cała funkcjonalność jest identyczna z pandami, ale wykorzystuje ona rozproszone biblioteki ramek danych, takie jak dask.
źródło
Powyższa odpowiedź już spełnia ten temat. W każdym razie, jeśli potrzebujesz wszystkich danych w pamięci - spójrz na bcolz . Kompresuje dane w pamięci. Miałem z tym naprawdę dobre doświadczenia. Ale brakuje mu wielu funkcji pand
Edycja: Mam współczynniki kompresji około 1/10 lub rozmiar oryginału, myślę, oczywiście w zależności od rodzaju danych. Ważnymi brakującymi funkcjami były agregaty.
źródło
chunks
Podejrzewam, że możesz wstępnie przetworzyć pandy przy użyciu wspomnianej metody, a następnie użyć bcolz, jeśli potrzebujesz wszystkich danych w pamięci, aby wykonać analizę. Tylko myśl.Możesz odczytać dane jako kawałki i zapisać każdy kawałek jako piklę.
W następnym kroku wczytujesz pikle i dołączasz każdą pikietę do żądanej ramki danych.
źródło
df
mieści się całkowicie w pamięci (jak sugeruje) i zawiera taką samą ilość danych, jak twoje dane wejściowe, to na pewno nie potrzebujesz w ogóle porcji?Funkcje read_csv i read_table są prawie takie same. Ale musisz przypisać ogranicznik „,”, gdy używasz funkcji read_table w swoim programie.
źródło
Rozwiązanie 1:
Korzystanie z pand z dużymi danymi
Rozwiązanie 2:
źródło
dfList.append
, po prostu przetwarzaj każdądf
Oto przykład:
źródło
Możesz wypróbować sframe, które mają tę samą składnię co pandy, ale pozwalają na manipulowanie plikami większymi niż twoja pamięć RAM.
źródło
Jeśli używasz pand, wczytaj duży plik do porcji, a następnie wydaj wiersz po rzędzie, oto co zrobiłem
źródło
Chcę udzielić bardziej kompleksowej odpowiedzi na podstawie większości potencjalnych rozwiązań, które już zostały dostarczone. Chciałbym również wskazać jeszcze jedną potencjalną pomoc, która może pomóc w procesie czytania.
Opcja 1: dtypy
„dtypes” to dość potężny parametr, którego można użyć do zmniejszenia presji pamięci na
read
metody. Zobacz tę i tę odpowiedź. Pandy domyślnie próbują wnioskować o typach danych.Odnosząc się do struktur danych, każde zapisane dane, następuje przydział pamięci. Na poziomie podstawowym zapoznaj się z poniższymi wartościami (tabela poniżej ilustruje wartości dla języka programowania C):
Sprawdź tę stronę, aby zobaczyć dopasowanie między NumPy i typami C.
Powiedzmy, że masz tablicę liczb z cyfr . Możesz zarówno teoretycznie, jak i praktycznie przypisać, powiedzmy tablicę 16-bitowych liczb całkowitych, ale wtedy przydzielisz więcej pamięci, niż faktycznie potrzebujesz do przechowywania tej tablicy. Aby temu zapobiec, możesz ustawić
dtype
opcję naread_csv
. Nie chcesz przechowywać elementów tablicy jako długich liczb całkowitych, gdzie faktycznie możesz zmieścić je za pomocą 8-bitowych liczb całkowitych (np.int8
lubnp.uint8
).Obserwuj poniższą mapę typu.
Źródło: https://pbpython.com/pandas_dtypes.html
Możesz przekazać
dtype
parametr jako parametr w metodach pand takread
jak w przypadku {kolumna: typ}.Opcja 2: odczytane przez kawałki
Odczytywanie danych we fragmentach umożliwia dostęp do części danych w pamięci, a także można zastosować wstępne przetwarzanie danych i zachować przetworzone dane zamiast danych surowych. Byłoby znacznie lepiej, gdyby połączyć tę opcję z pierwszą, dtypami .
Chciałbym wskazać sekcje książki kucharskiej pandy dotyczące tego procesu, gdzie można je znaleźć tutaj . Zwróć uwagę na te dwie sekcje;
Opcja 3: Dask
Dask to środowisko, które jest zdefiniowane na stronie internetowej Dask jako:
Urodził się, aby pokryć niezbędne części, do których nie mogą dotrzeć pandy. Dask to potężny framework, który pozwala na znacznie większy dostęp do danych poprzez przetwarzanie ich w sposób rozproszony.
Możesz użyć dask, aby wstępnie przetworzyć swoje dane jako całość, Dask zajmuje się fragmentacją, więc w przeciwieństwie do pand, możesz po prostu zdefiniować etapy przetwarzania i pozwolić Dask wykonać pracę. Dask nie dotyczy obliczeń zanim zostanie ona wyraźnie przesunąć
compute
i / lubpersist
(patrz odpowiedź tutaj różnicy).Inne pomoce (pomysły)
źródło
Oprócz powyższych odpowiedzi, dla tych, którzy chcą przetworzyć CSV, a następnie wyeksportować do formatu csv, parquet lub SQL, d6tstack to kolejna dobra opcja. Możesz załadować wiele plików i dotyczy to zmian schematu danych (dodanych / usuniętych kolumn). Wydzielone z podstawowego wsparcia jest już wbudowane.
źródło
W przypadku, gdy ktoś wciąż szuka czegoś takiego, odkryłem, że ta nowa biblioteka o nazwie modin może pomóc. Wykorzystuje przetwarzanie rozproszone, które może pomóc w czytaniu. Oto fajny artykuł porównujący jego funkcjonalność z pandami. Zasadniczo wykorzystuje te same funkcje, co pandy.
źródło
modin
wypada w porównaniu z dobrze ugruntowaną pozycjądask.dataframe
? Na przykład zobacz przenoszenie z pand do dask, aby wykorzystać wszystkie lokalne rdzenie procesora .Przed użyciem opcji chunksize, jeśli chcesz być pewien funkcji procesu, którą chcesz zapisać w pętli for chunking, jak wspomniano w @unutbu, możesz po prostu użyć opcji nrows.
Gdy masz pewność, że blok procesu jest gotowy, możesz umieścić go w pętli łączenia dla całej ramki danych.
źródło