Marco de datos de pandas: ¿seleccionar filas y borrar memoria?

Tengo un gran dataframe de pandas (tamaño = 3 GB):

x = read.table (‘big_table.txt’, sep = ‘\ t’, header = 0, index_col = 0)

Debido a que estoy trabajando bajo restricciones de memoria, subconjunto el dataframe:

rows = Calculate_rows () # una función que calcula qué filas necesito

cols = Calculate_cols () # una función que calcula qué cols necesito

x = x.ix [filas, columnas]

Las funciones que calculan las filas y columnas no son importantes, pero son DEFINITIVAMENTE un subconjunto más pequeño de las filas y columnas originales. Sin embargo, cuando hago esta operación, ¡el uso de memoria aumenta mucho! El objective original era reducir la huella de memoria a menos de 3 GB, pero en cambio, el uso de la memoria supera los 6 GB.

Supongo que esto se debe a que Python crea una copia local del dataframe en la memoria, pero no lo limpia. También puede haber otras cosas que estén sucediendo … Entonces, mi pregunta es ¿cómo puedo subcontratar un gran dataframe y limpiar el espacio? No puedo encontrar una función que seleccione filas / cols en su lugar.

He leído un montón de desbordamiento de stack, pero no puedo encontrar mucho sobre este tema. Podría ser que no esté usando las palabras clave adecuadas, así que si tiene sugerencias, eso también podría ayudar. ¡Gracias!

Estás mucho mejor haciendo algo como esto:

Especifique usecols para sub-seleccionar qué columnas desea en primer lugar para read_csv , vea aquí .

Luego lea el archivo en fragmentos, vea aquí , si las filas que desea están seleccionadas, desvíenlas para que concatenen el resultado.

Pseudo-código ish:

 reader = pd.read_csv('big_table.txt', sep='\t', header=0, index_col=0, usecols=the_columns_i_want_to_use, chunksize=10000) df = pd.concat([ chunk.ix[rows_that_I_want_] for chunk in reader ]) 

Esto tendrá un uso de memoria constante (el tamaño de un trozo)

más el uso de las filas seleccionadas x 2, lo que sucederá cuando concat las filas después de la concat, el uso se reducirá al uso de las filas seleccionadas

He tenido un problema similar, lo resolví con un filtro de datos antes de cargar. Cuando lee el archivo con read.table, está cargando el conjunto en un DataFrame, y quizás también el archivo completo en la memoria o alguna duplicación debido al uso de diferentes tipos, por lo que este es el 6GB utilizado.

Podría hacer un generador para cargar el contenido del archivo línea por línea, asumo que los datos se basan en filas, un registro es una fila y una línea en big_table.txt, así que

 def big_table_generator(filename): with open(filename, 'rt') as f: for line in f: if is_needed_row(line): #Check if you want this row #cut_columns() return a list with only the selected columns record = cut_columns(line) yield column gen = big_table_generator('big_table.txt') df = pandas.DataFrame.from_records(list(gen)) 

Tenga en cuenta que la lista (gen), pandas 0.12 y la versión anterior no permiten generadores, por lo que debe convertirlos en una lista para que todos los datos proporcionados por el generador se almacenen en la memoria. 0.13 hará lo mismo internamente. También necesita el doble de la memoria de los datos que necesita, uno para cargar los datos y otro para ponerlos en la estructura de dataframe de pandas.

También puede hacer que el generador lea desde un archivo comprimido, con la biblioteca python 3.3 gzip solo descomprima los chuncks necesarios.