Obecnie próbuję odczytać dane z plików .csv w Pythonie 2.7 z maksymalnie 1 milionem wierszy i 200 kolumnami (zakres plików od 100 MB do 1,6 GB). Mogę to zrobić (bardzo powoli) dla plików z mniej niż 300 000 wierszy, ale gdy przejdę powyżej, pojawiają się błędy pamięci. Mój kod wygląda tak:
def getdata(filename, criteria):
data=[]
for criterion in criteria:
data.append(getstuff(filename, criteron))
return data
def getstuff(filename, criterion):
import csv
data=[]
with open(filename, "rb") as csvfile:
datareader=csv.reader(csvfile)
for row in datareader:
if row[3]=="column header":
data.append(row)
elif len(data)<2 and row[3]!=criterion:
pass
elif row[3]==criterion:
data.append(row)
else:
return data
Powodem zastosowania klauzuli else w funkcji getstuff jest to, że wszystkie elementy, które pasują do kryterium, zostaną wymienione razem w pliku csv, więc zostawiam pętlę, gdy mijam je, aby zaoszczędzić czas.
Moje pytania to:
Jak mogę to zrobić z większymi plikami?
Czy jest jakiś sposób, żebym mógł to przyspieszyć?
Mój komputer ma 8 GB pamięci RAM, 64-bitowy system Windows 7, a procesor ma 3,40 GHz (nie wiem, jakich informacji potrzebujesz).
python
python-2.7
file
csv
Charles Dillon
źródło
źródło
Odpowiedzi:
Wczytujesz wszystkie wiersze na listę, a następnie przetwarzasz tę listę. Nie rób tego .
Przetwarzaj wiersze w miarę ich tworzenia. Jeśli musisz najpierw przefiltrować dane, użyj funkcji generatora:
Uprościłem również twój test filtra; logika jest taka sama, ale bardziej zwięzła.
Ponieważ dopasowujesz tylko jedną sekwencję wierszy pasujących do kryterium, możesz również użyć:
Możesz teraz wykonać pętlę
getstuff()
bezpośrednio. Zrób to samo wgetdata()
:Teraz pętla bezpośrednio
getdata()
w kodzie:Teraz masz w pamięci tylko jeden wiersz , zamiast tysięcy wierszy na kryterium.
yield
przekształca funkcję w funkcję generatora , co oznacza, że nie będzie ona działać, dopóki nie zaczniesz nad nią zapętlać.źródło
csv.DictReader
? Ponieważ moje testy na pliku .csv o pojemności 2,5 GB pokazują, że próba iteracji wiersz po wierszu w ten sposób podczas używania tego zamiastcsv.reader
powoduje, że proces Pythona rośnie do pełnego wykorzystania pamięci 2,5 GB.Chociaż odpowiedź Martijina jest najlepsza. Oto bardziej intuicyjny sposób przetwarzania dużych plików CSV dla początkujących. Pozwala to na jednoczesne przetwarzanie grup wierszy lub fragmentów.
źródło
Wykonuję sporo analiz drgań i patrzę na duże zbiory danych (dziesiątki i setki milionów punktów). Moje testy wykazały, że funkcja pandas.read_csv () jest 20 razy szybsza niż numpy.genfromtxt (). Funkcja genfromtxt () jest 3 razy szybsza niż numpy.loadtxt (). Wygląda na to, że potrzebujesz pand do dużych zbiorów danych.
Opublikowałem kod i zestawy danych, których użyłem w tych testach, na blogu omawiającym MATLAB vs Python do analizy drgań .
źródło
to, co zadziałało, było i jest superszybkie
Innym działającym rozwiązaniem jest:
źródło
df_train=df_train.compute()
linia w twoim pierwszym rozwiązaniu nie ładuje całego zbioru danych do pamięci ... czego on stara się nie robić?Dla kogoś, kto zadaje to pytanie. Używanie pand z parametrami „ chunksize ” i „ usecols ” pomogło mi odczytać ogromny plik zip szybciej niż inne proponowane opcje.
źródło
oto inne rozwiązanie dla Python3:
tutaj
datareader
jest funkcja generatora.źródło
Jeśli używasz pandy i mieć dużo pamięci RAM (wystarczający aby przeczytać cały plik do pamięci), spróbuj skorzystać
pd.read_csv
zlow_memory=False
, na przykład:źródło