2016-04-06 14 views
3

Ich habe sehr einfaches Skript, das pandas.parse_csv Methode verwendet, um große Datenmenge zu laden.Pandas read_csv ist super langsam auf NFS

import pandas as pd 
import numpy as np 

USE_COLUMNS = [0,1,2,11,13,14] 

def parse_csv(filename): 
    df = pd.read_csv(filename, 
        header=None, 
        compression='bz2', 
        delim_whitespace=True, 
        dtype={11:np.float32, 13:np.float32, 14:np.float32}, 
        skip_blank_lines=True, 
        skiprows=4, 
        parse_dates=[[1,2]], 
        usecols=USE_COLUMNS, 
        error_bad_lines=False, 
        infer_datetime_format=True, 
        iterator=True, 
        chunksize=100000, 
        low_memory=False, 
        engine='c') 
    return df 

fname = 'test.log.bz2' 
iter = parse_csv(fname) 
df = pd.concat([chunk[chunk[14] > 60000] for chunk in iter]) 
print df 

Datei test.log.bz2 ist 1,1 GB komprimiert und 5 + GB unkomprimiert, es hat 15 Spalten nur einige von ihnen verwendet wird. Auf meinem lokalen Rechner benötigt dieses Skript etwa 200 Sekunden. Aber auf der Produktionsmaschine läuft es 53 Minuten (x16 Verlangsamung)! Wie kann ich das beheben?

Auf meinem lokalen Computer verwende ich SATA SSD und auf Produktionsmaschine NFS-gesichertes Dateisystem ist die einzige Option.

Ich benutze Pandas Version 0.16.2.

ich dieses Skript auf meinem lokalen Rechner unter strace ist diese Ergebnisse:

% time  seconds usecs/call  calls errors syscall 
------ ----------- ----------- --------- --------- ---------------- 
57.09 0.038753   2  15618   mremap 
18.83 0.012780   0 109476   munmap 
14.81 0.010055   0 109669   mmap 
    3.44 0.002337   0 259922   read 
    2.10 0.001427   0  5549  4780 open 
    1.45 0.000987   1  713   brk 

strace Ergebnisse in der Produktionsumgebung:

% time  seconds usecs/call  calls errors syscall 
------ ----------- ----------- --------- --------- ---------------- 
92.41 0.491816   46  10766   mremap 
    4.59 0.024412   7  3491  2814 open 
    0.76 0.004065   0  9897   read 
    0.75 0.003999   15  274  274 unlink 
    0.50 0.002652   3  974  838 stat 
    0.47 0.002498  1249   2   clone 
    0.35 0.001865   0  4659   munmap 
------ ----------- ----------- --------- --------- ---------------- 
100.00 0.532200     37118  3997 total 
+0

gut tune up, setzen Sie Ihre Produktion NFS auf SSDs verwenden 10GiB Ethernet und dann können Sie Ihre Geschwindigkeit vergleichen;) Jetzt im ernst - ich über HD denken würde anfangen FS und Apache Spark für 5 + GB-Dateien – MaxU

+0

Ich kann diese Archivdatei in 10 Sekunden auf der Produktionsmaschine entpacken. – Lazin

+0

Wie lange dauert es, die gepackte Datei auf die Maschine zu kopieren, auf der Pandas läuft, und sie dort auszupacken? Ich meine nur diese beiden Operationen, ohne CSV zu lesen/zu analysieren ... – MaxU

Antwort

0

Ich würde Ihnen vorschlagen, um Ihre Daten Vorfilter (unter Verwendung von Standardwerkzeugen: bzip2 und gawk) vor dem Einlegen in Pandas:

bzip2 -dc /path/to/test.log.bz2 | gawk -F"," 'NR > 4 && $15 > 600000.0 {print}' > /path/to/test_filtered.log 

sollte dies viel schneller und viel weniger Speicher

achten Sie bitte auf $15 statt chunk[14] verbrauchen - AWK zählt Spalten von 1

danach starten Sie einfach vorgefilterten unkomprimierte CSV in Pandas

laden

PS Sie auch Ihre NFS möchten

Verwandte Themen