2012-11-15 7 views
6

Jestem całkiem nowym użytkownikiem Pythona i programowania w ogóle, ale próbuję uruchomić obliczenia "przesuwania okna" nad plikiem .txt rozdzielonym tabulatorami, który zawiera około 7 milionów linii z pytonem . Przez przesuwanie okna rozumiem, że wykona on obliczenia, powiedzmy 50 000 linii, zgłoś liczbę, a następnie przesuń w górę, powiedz 10 000 linii i wykonaj te same obliczenia w porównaniu z kolejnymi 50 000 linii. Mam obliczenia i "przesuwne okno" działające poprawnie i działa dobrze, jeśli testuję je na małym podzbiorze moich danych. Jednak jeśli spróbuję uruchomić program w całym zestawie danych, jest on niesamowicie wolny (miałem go uruchomionych przez około 40 godzin). Matematyka jest dość prosta, więc nie sądzę, że powinno to potrwać tak długo.Przetwarzanie dużego pliku .txt w pytonie efektywnie

Sposób w jaki teraz czytam plik .txt jest w module csv.DictReader. Mój kod wygląda następująco:

file1='/Users/Shared/SmallSetbee.txt' 
newfile=open(file1, 'rb') 
reader=csv.DictReader((line.replace('\0','') for line in newfile), delimiter="\t") 

wierzę, że to czyni słownika Spośród wszystkich 7 milionów wierszy na raz, co myślę, że może być przyczyną tego, że spowalnia tyle dla większego pliku.

Ponieważ interesuje mnie tylko wykonywanie obliczeń przez "porcje" lub "okna" danych na raz, czy istnieje skuteczniejszy sposób czytania tylko w określonych wierszach na raz, wykonanie obliczeń, a następnie powtórzenie z nowy określony "porcja" lub "okno" określonych linii?

+1

Nie tworzy to słownika wszystkich linii naraz. Tworzy słownik dla każdej linii. Oznacza to, że opublikowany fragment nie jest przyczyną problemów z wydajnością. Być może mógłbyś nam pokazać więcej kodu? –

+1

Podejrzewam, że jeśli robisz obliczenia na dużych zestawach danych podobnych do tabel, możesz zajrzeć do Pand: http://pandas.pydata.org/pandas-docs/dev/io.html#iterating-through- files-chunk-by-chunk Wszystko, co próbujesz zrobić, zostało prawdopodobnie zrobione przed 1000 razy lepszym. – Iguananaut

+0

Te obliczenia wykonasz w 696 "oknach". Ile czasu zajmuje jedno okno na pliku linii 50k? –

Odpowiedz

6

A collections.deque to uporządkowany zbiór przedmiotów, które mogą mieć maksymalny rozmiar. Kiedy dodajesz element do jednego końca, jeden spada z drugiego końca. Oznacza to, że aby powtórzyć "okienko" na twoim CSV, musisz tylko dodawać wiersze do deque i zajmie się on już wyrzucaniem kompletnych.

dq = collections.deque(maxlen=50000) 
with open(...) as csv_file: 
    reader = csv.DictReader((line.replace("\0", "") for line in csv_file), delimiter="\t") 

    # initial fill 
    for _ in range(50000): 
     dq.append(reader.next()) 

    # repeated compute 
    try: 
     while 1: 
      compute(dq) 
      for _ in range(10000): 
       dq.append(reader.next()) 
    except StopIteration: 
      compute(dq) 
+1

'try/except' powinien znajdować się bliżej' reader.next() ', aby uniknąć przypadkowe łapanie 'StopIteration' z' compute (dq) ' – jfs

3

Nie używaj csv.DictReader, zamiast używać csv.reader. Utworzenie słownika dla każdego wiersza zajmuje więcej czasu niż utworzenie listy dla każdego wiersza. Ponadto dostęp do listy przez indeks jest marginalnie szybszy niż dostęp do słownika za pomocą klucza.

Wykonałem iterację czasową dla pliku csv o wartości 300 000 linii, używając dwóch czytników CSV. csv.DictReader przejął siedem razy dłużej niż csv.reader.

Połączyć to z katrielalex's suggestion, aby użyć collections.deque, a powinieneś zobaczyć ładne przyspieszenie.

Dodatkowo, profile twój kod, aby wskazać, gdzie spędzasz większość swojego czasu.