Come evitare errori di memoria

4

Sto lavorando con file abbastanza grandi (pytables) e sto riscontrando problemi con Memory Error quando provo a caricare i dati per l'elaborazione.

Vorrei alcuni suggerimenti su come evitare questo nei miei python 32bit, dal momento che sto lavorando su panda e pytables e non so come dividere i dati in piccoli pezzi.

La mia preoccupazione arriva anche quando, se riesco a dividere i dati, come calcolare statistiche come media, std, ecc senza l'intero elenco o array, ecc.

Questo è un esempio del codice che sto usando ora, questo funziona bene con le tabelle di piccole dimensioni:

def getPageStats(pathToH5, pages, versions, sheets):

    with openFile(pathToH5, 'r') as f:
        tab = f.getNode("/pageTable")

        dversions = dict((i, None) for i in versions)
        dsheets = dict((i, None) for i in sheets)
        dpages = dict((i, None) for i in pages)


        df = pd.DataFrame([[row['page'],row['index0'], row['value0'] ] for row in tab.where('(firstVersion == 0) & (ok == 1)') if  row['version'] in dversions and row['sheetNum'] in dsheets and row['pages'] in dpages ], columns=['page','index0', 'value0'])        
        df2 = pd.DataFrame([[row['page'],row['index1'], row['value1'] ] for row in tab.where('(firstVersion == 1) & (ok == 1)') if  row['version'] in dversions and row['sheetNum'] in dsheets and row['pages'] in dpages], columns=['page','index1', 'value1'])        

        for i in dpages:


            m10 = df.loc[df['page']==i]['index0'].mean()
            s10 = df.loc[df['page']==i]['index0'].std()

            m20 = df.loc[df['page']==i]['value0'].mean()
            s20 = df.loc[df['page']==i]['value0'].std()

            m11 = df2.loc[df2['page']==i]['index1'].mean()
            s11 = df2.loc[df2['page']==i]['index1'].std()

            m21 = df2.loc[df2['page']==i]['value1'].mean()
            s21 = df2.loc[df2['page']==i]['value1'].std()

            yield (i,m10, s10), (i,m11, s11), (i,m20,s20), (i,m21,s21)) 

Come puoi vedere, sto caricando tutti i dati necessari in un DataFrame di Pandas per processarlo, solo la media e lo standard adesso.

Questo è abbastanza veloce, ma per un pasticcio con 22Milioni di righe ottengo Memory Error

    
posta codeKiller 18.06.2014 - 11:22
fonte

2 risposte

5

Per quanto ne so, Pandas non è lo strumento migliore se non riesci a memorizzare tutto nella memoria.

Inoltre stai creando alcuni dati extra che potresti cercare di evitare. Sto parlando delle list comprehensions.

Per una volta sono un po 'troppo grandi / complessi per essere una lista di comprensione come per me.

In secondo luogo, a causa della sua natura per un breve periodo di tempo, ci sono troppi dati: la lista completa + la sua rappresentazione di copia all'interno di DataFrame. Con il secondo compito ( df2 ) hai in mano un nuovo DF, l'elenco e df . Per non parlare di tutti gli altri oggetti che hai già creato.

  1. Prova ad usare un generatore invece di una comprensione di lista. In linea sostituendo [...] con (...) o un generatore appropriato che sarà più leggibile.

  2. (Quando la soluzione 1 non è sufficiente) Drop Pandas ed eseguire i calcoli manualmente. Questo potrebbe richiedere di ripetere due volte i dati, ma ti darà il risultato.

risposta data 21.06.2014 - 20:16
fonte
0

Hai provato a utilizzare groupby e merge ? Penso che ridurrà in modo significativo il sovraccarico di codice e memoria. Ecco un tentativo di riscrivere il tuo codice. Non ho provato, ma dovresti avere l'idea.

def getPageStats(pathToH5, pages, versions, sheets): with openFile(pathToH5, 'r') as f: tab = f.getNode("/pageTable") # Avoid looping over rows, the following is way more efficient d = pd.DataFrame({ 'version': dversions, 'sheetNum': dsheets, 'pages': dpages }) d_fv0_ok1 = tab.where('(firstVersion == 0) & (ok == 1)') # Join on the two dataframe to obtain the rows that you are # looking for df = pd.merge(left=tab, right=d_fv0_ok1, on=['version', 'sheetNum', 'pages'], how='inner', copy=False) dfg = df.groupby('page').agg(['mean', 'std']) ## dfg is a multi index dataframe. # You can access them by dfg.loc[pageid, ('index0', 'mean')], etc. return dfg.join(d.pages, how='inner')

    
risposta data 19.03.2018 - 13:09
fonte

Leggi altre domande sui tag