Muszę czytać duży plik, wiersz po wierszu. Powiedzmy, że plik ma więcej niż 5 GB i muszę przeczytać każdą linię, ale oczywiście nie chcę jej używać, readlines()
ponieważ utworzy bardzo dużą listę w pamięci.
Jak działa poniższy kod dla tego przypadku? Czy xreadlines
sam czyta jedno po drugim do pamięci? Czy potrzebne jest wyrażenie generatora?
f = (line for line in open("log.txt").xreadlines()) # how much is loaded in memory?
f.next()
Ponadto, co mogę zrobić, aby przeczytać to w odwrotnej kolejności, podobnie jak tail
polecenie Linux ?
Znalazłem:
http://code.google.com/p/pytailer/
i
„ Głowa, ogon i tył pytona czytane liniami pliku tekstowego ”
Oba działały bardzo dobrze!
Odpowiedzi:
Podałem tę odpowiedź, ponieważ Keith's, choć zwięzły, nie zamyka pliku jawnie
źródło
for
pętli, która iteruje po liniach, możesz użyćchunk = infile.read(chunksize)
do odczytu fragmentów o ograniczonym rozmiarze, niezależnie od ich zawartości. Musisz samodzielnie przeszukać fragmenty nowych linii.Wszystko, co musisz zrobić, to użyć obiektu pliku jako iteratora.
Jeszcze lepsze jest użycie menedżera kontekstu w najnowszych wersjach Pythona.
Spowoduje to również automatyczne zamknięcie pliku.
źródło
Podejście starej szkoły:
źródło
Lepiej zamiast tego użyj iteratora. Odpowiedni: http://docs.python.org/library/fileinput.html
Z dokumentów:
Pozwoli to uniknąć jednoczesnego kopiowania całego pliku do pamięci.
źródło
close()
metody zwracanegoFileInput
obiektu klasy po zakończeniu pętli - dlatego unikałbym używania go w ten sposób. W Pythonie 3.2 w końcu są onefileinput
zgodne z protokołem menedżera kontekstu, który rozwiązuje ten problem (ale kod nadal nie byłby napisany w sposób pokazany na rysunku).Oto, co robisz, jeśli w pliku nie ma nowych linii:
źródło
Spróbuj tego:
źródło
Nie mogłem uwierzyć, że może to być tak proste, jak się wydaje odpowiedź @ john-la-rooy. Tak więc odtworzyłem
cp
polecenie za pomocą odczytu i zapisu wiersz po wierszu. CRAZY FAST.źródło
readline
standaryzuje zakończenia linii, ma to efekt uboczny konwersji dokumentów z zakończeniami linii DOS-a\r\n
na uniksowe zakończenia linii\n
. Cały mój powód do poszukiwania tego tematu polegał na tym, że musiałem przekonwertować plik dziennika, który odbiera zbiór zakończeń linii (ponieważ programista ślepo korzystał z różnych bibliotek .NET). Byłem zszokowany, gdy stwierdziłem, że po pierwszym teście prędkości nie musiałem wracać irstrip
linii. To było już idealne!Projekt blask przeszedł długą drogę w ciągu ostatnich 6 lat. Ma prosty interfejs API obejmujący użyteczny podzbiór funkcji pand.
dask.dataframe dba o wewnętrzne dzielenie , obsługuje wiele równoległych operacji i pozwala łatwo eksportować wycinki z powrotem do pand w celu wykonania operacji w pamięci.
źródło
Oto kod ładowania plików tekstowych dowolnej wielkości bez powodowania problemów z pamięcią. Obsługuje pliki wielkości gigabajtów
https://gist.github.com/iyvinjose/e6c1cb2821abd5f01fd1b9065cbc759d
pobierz plik data_loading_utils.py i zaimportuj go do swojego kodu
stosowanie
linie_procesoweMetoda to funkcja zwrotna. Zostanie wywołany dla wszystkich linii, przy czym dane parametrów reprezentują jedną linię pliku na raz.
Możesz skonfigurować zmienną CHUNK_SIZE w zależności od konfiguracji sprzętowych maszyny.
źródło
Co powiesz na to? Podziel plik na części, a następnie przeczytaj wiersz po wierszu, ponieważ gdy czytasz plik, system operacyjny buforuje następny wiersz. Jeśli czytasz plik linia po linii, nie wykorzystujesz skutecznie buforowanych informacji.
Zamiast tego podziel plik na części i załaduj cały fragment do pamięci, a następnie wykonaj przetwarzanie.
źródło
Dziękuję Ci! Niedawno przekonwertowałem na Python 3 i byłem sfrustrowany przez użycie readlines (0) do odczytu dużych plików. To rozwiązało problem. Ale aby uzyskać każdą linię, musiałem zrobić kilka dodatkowych kroków. Każda linia była poprzedzona literą „b”, która, jak sądzę, była w formacie binarnym. Użycie „dekodowania (utf-8)” zmieniło to ascii.
Następnie musiałem usunąć „= \ n” na środku każdej linii.
Następnie podzielę linie na nowej linii.
Oto kod zaczynający się tuż nad „drukuj dane” w kodzie Arohi.
źródło
W tym innym pytaniu zademonstrowałem podejście losowego dostępu na poziomie bajtów.
Uzyskiwanie liczby wierszy w pliku tekstowym bez linii readline
Niektóre z udzielonych odpowiedzi są ładne i zwięzłe. Lubię niektóre z nich. Ale tak naprawdę zależy od tego, co chcesz zrobić z danymi zawartymi w pliku. W moim przypadku chciałem tylko jak najszybciej policzyć linie na dużych plikach tekstowych. Mój kod można oczywiście modyfikować, aby wykonywać także inne czynności, takie jak dowolny kod.
źródło
Najlepsze rozwiązanie, jakie znalazłem, i wypróbowałem to na pliku 330 MB.
Gdzie długość_linii to liczba znaków w jednym wierszu. Na przykład „abcd” ma długość linii 4.
Dodałem 2 w linii, aby pominąć znak „\ n” i przejść do następnego znaku.
źródło
Może to być przydatne, gdy chcesz pracować równolegle i odczytywać tylko fragmenty danych, ale utrzymywać je w czystości dzięki nowym wierszom.
źródło
mam nadzieję że to pomoże.
źródło