Reduzca el uso de memoria de este código Pandas de lectura de código Pandas y decapado

No puedo encontrar una manera de reducir aún más el uso de memoria para este progtwig. Básicamente, estoy leyendo archivos de registro JSON en un dataframe de pandas, pero:

  1. La función de append lista es lo que está causando el problema. Crea dos objetos diferentes en la memoria, causando un gran uso de memoria.
  2. .to_pickle método .to_pickle de los pandas también es un gran problema de memoria, porque el mayor aumento en la memoria es cuando se escribe en el pickle.

Aquí está mi implementación más eficiente hasta la fecha:

 columns = ['eventName', 'sessionId', "eventTime", "items", "currentPage", "browserType"] df = pd.DataFrame(columns=columns) l = [] for i, file in enumerate(glob.glob("*.log")): print("Going through log file #%s named %s..." % (i+1, file)) with open(file) as myfile: l += [json.loads(line) for line in myfile] tempdata = pd.DataFrame(l) for column in tempdata.columns: if not column in columns: try: tempdata.drop(column, axis=1, inplace=True) except ValueError: print ("oh no! We've got a problem with %s column! It don't exist!" % (badcolumn)) l = [] df = df.append(tempdata, ignore_index = True) # very slow version, but is most memory efficient # length = len(df) # length_temp = len(tempdata) # for i in range(1, length_temp): # update_progress((i*100.0)/length_temp) # for column in columns: # df.at[length+i, column] = tempdata.at[i, column] tempdata = 0 print ("Data Frame initialized and filled! Now Sorting...") df.sort(columns=["sessionId", "eventTime"], inplace = True) print ("Done Sorting... Changing indices...") df.index = range(1, len(df)+1) print ("Storing in Pickles...") df.to_pickle('data.pkl') 

¿Hay una manera fácil de reducir la memoria? El código comentado hace el trabajo pero toma 100-1000x más. Actualmente tengo un uso de memoria del 45% como máximo durante la parte .to_pickle , el 30% durante la lectura de los registros. Pero cuantos más registros haya, mayor será el número.

Esta respuesta es para la optimización del uso de la memoria general de pandas dataFrame:

  1. Pandas carga en columnas de cadena como tipo de objeto por defecto. Para todas las columnas que tienen el objeto de tipo, intente asignar la categoría de tipo a estas columnas pasando un diccionario a los tipos de parámetros de la función read_csv . El uso de la memoria disminuye dramáticamente para las columnas con valores únicos del 50% o menos.

  2. Pandas lee en columnas numéricas como float64 por defecto. Use pd.to_numeric para reducir el tipo float64 a 32 o 16 si es posible. Esto de nuevo te guarda la memoria.

  3. Cargar en trozos de datos csv por trozo . Procésalo, y pasa a la siguiente parte . Esto se puede hacer especificando un valor para el parámetro chunk_size del método read_csv .

Si necesita construir un DataFrame a partir de piezas, generalmente es mucho más eficiente construir una lista de los marcos de componentes y combinarlos todos en un solo paso utilizando concat . Vea el primer acercamiento a continuación.

 # df = 10 rows of dummy data In [10]: %%time ...: dfs = [] ...: for _ in xrange(1000): ...: dfs.append(df) ...: df_concat = pd.concat(dfs, ignore_index=True) ...: Wall time: 42 ms In [11]: %%time ...: df_append = pd.DataFrame(columns=df.columns) ...: for _ in xrange(1000): ...: df_append = df_append.append(df, ignore_index=True) ...: Wall time: 915 ms