2017-09-26 1 views
0

Ziel ist es, RMSE zwischen zwei Gruppen von Spalten in einem Pandas-Datenrahmen zu berechnen. Das Problem ist, dass die tatsächlich verwendete Speichergröße fast das Zehnfache der Größe des Datenrahmens beträgt. Hier ist der Code, den ich verwendet RMSE zu berechnen:Speicherfehler bei der Ausführung von Operationen auf Pandas Dataframe slice

import pandas as pd 
import numpy as np 
from random import shuffle 

# set up test df (actual data is a pre-computed DF stored in HDF5) 
dim_x, dim_y = 50, 1000000 # actual dataset dim_y = 56410949 
cols = ["a_"+str(i) for i in range(1,(dim_x//2)+1)] 
cols_b = ["b_"+str(i) for i in range(1,(dim_x//2)+1)] 
cols.extend(cols_b) 
df = pd.DataFrame(np.random.uniform(0,10,[dim_y, dim_x]), columns=cols) 


# calculate rmse : https://stackoverflow.com/a/46349518 
a = df.values 
diffs = a[:,1:26] - a[:,26:27] 
rmse_out = np.sqrt(np.einsum('ij,ij->i',diffs,diffs)/3.0) 

df['rmse_out'].to_pickle('results_rmse.p') 

Wenn ich die Werte aus der df erhalten mit a = df.values, die Speichernutzung für diese Routine nähert sich 100GB nach oben. Die Routine berechnet den Unterschied zwischen diesen Spalten, diffs = a[:,1:26] - a[:,26:27], Ansätze 120 GB erzeugt dann einen Speicherfehler. Wie kann ich meinen Code ändern, um den Speicher effizienter zu machen, den Fehler zu vermeiden und meine RMSE-Werte tatsächlich zu berechnen?

+0

Ein Weg wäre, eine Reihe von Zeilen zu zerlegen und es iterativ zu tun. Fügen Sie auch einen Link hinzu, von dem Sie diesen Code abgeholt haben, denn ich erinnere mich, diesen Code gesehen zu haben :) – Divakar

+0

Zitierte Sie @Divakar –

+2

Wie wäre es mit: 's0, s1 = a [:, 1:26], a [:, 26 : 27]; rmse_out = np.sqrt (ne.evaluate ("Summe ((s0-s1) ** 2,1)")/3.0) ', wobei' ne' ein externes Modul ist: 'import numexpr as ne'? – Divakar

Antwort

1

war die Lösung, die ich verwenden, um den Datenrahmen zu Brocken hinunter:

df = pd.read_hdf('madre_merge_sort32.h5') 
for i,d in enumerate(np.array_split(df, 10)): 
    d.to_pickle(str(i)+".p") 

Dann lief durch ich diesen eingelegten Mini-dfs und berechnet rmse in jedem:

for fn in glob.glob("*.p"): 
    # process df values 
    df = pd.read_pickle(fn) 
    df.replace([np.inf, -np.inf], np.nan, inplace=True) 
    df.dropna(inplace=True) 
    a= df[df.columns[2:]].as_matrix() # first two cols are non-numeric, so skip 

    # calculate rmse 
    diffs = a[:,:25] - a[:,25:] 
    rmse_out = np.sqrt(np.einsum('ij,ij->i',diffs,diffs)/3.0) 

    df['rmse_out'] = rmse_out 
    df.to_pickle("out"+fn) 

Dann sie ich verketteten:

dfls = [] 
for fn in glob.glob("out*.p"): 
    df = pd.read_pickle(fn) 
    dfls.append(df) 
dfcat = pd.concat(dfls) 

Chunking schien für mich zu arbeiten.

Verwandte Themen