DataFrame grande y persistente en pandas

Resuelto Zelazny7 asked hace 12 años • 6 respuestas

Estoy explorando cambiar a Python y Pandas como usuario de SAS desde hace mucho tiempo.

Sin embargo, al ejecutar algunas pruebas hoy, me sorprendió que Python se quedara sin memoria al intentar crear pandas.read_csv()un archivo csv de 128 MB. Tenía alrededor de 200.000 filas y 200 columnas de datos en su mayoría numéricos.

Con SAS, puedo importar un archivo csv a un conjunto de datos SAS y puede ser tan grande como mi disco duro.

¿ Hay algo análogo en pandas?

Trabajo habitualmente con archivos grandes y no tengo acceso a una red informática distribuida.

Zelazny7 avatar Jul 24 '12 07:07 Zelazny7
Aceptado

¡Wes, por supuesto, tiene razón! Solo estoy interviniendo para proporcionar un código de ejemplo un poco más completo. Tuve el mismo problema con un archivo de 129 Mb, que se resolvió mediante:

import pandas as pd
    
# Returns a TextFileReader, which is iterable with chunks of 1000 rows.
csv_iterator = pd.read_csv('large_dataset.csv', iterator=True, chunksize=1000)
# Iterate through the dataframe chunks and print one row/record at a time
for chunk in csv_iterator:
    for index, row in chunk.iterrows():
        print(row)

# df is DataFrame. If errors, use `list(csv_iterator)` instead
df = pd.concat(tp, ignore_index=True)
fickludd avatar Aug 30 '2012 08:08 fickludd

En principio, no debería quedarse sin memoria, pero actualmente hay problemas de memoria con read_csvarchivos grandes causados ​​por algunos problemas internos complejos de Python (esto es vago pero se sabe desde hace mucho tiempo: http://github.com/pydata /pandas/issues/407 ).

Por el momento no existe una solución perfecta (aquí hay una tediosa: puede transcribir el archivo fila por fila en una matriz NumPy preasignada o en un archivo mapeado en memoria np.mmap), pero es una en la que estaré trabajando. en un futuro próximo. Otra solución es leer el archivo en partes más pequeñas (use iterator=True, chunksize=1000) y luego concatenarlo con pd.concat. El problema surge cuando guardas todo el archivo de texto en la memoria de un solo gran sorbo.

Wes McKinney avatar Jul 24 '2012 01:07 Wes McKinney

Este es un hilo antiguo, pero solo quería dejar mi solución alternativa aquí. Inicialmente probé el chunksizeparámetro (incluso con valores bastante pequeños como 10000), pero no ayudó mucho; Todavía tenía problemas técnicos con el tamaño de la memoria (mi CSV era ~ 7,5 Gb).

En este momento, simplemente leo fragmentos de archivos CSV en un enfoque de bucle for y los agrego, por ejemplo, a una base de datos SQLite paso a paso:

import pandas as pd
import sqlite3
from pandas.io import sql
import subprocess

# In and output file paths
in_csv = '../data/my_large.csv'
out_sqlite = '../data/my.sqlite'

table_name = 'my_table' # name for the SQLite database table
chunksize = 100000 # number of lines to process at each iteration

# columns that should be read from the CSV file
columns = ['molecule_id','charge','db','drugsnow','hba','hbd','loc','nrb','smiles']

# Get number of lines in the CSV file
nlines = subprocess.check_output('wc -l %s' % in_csv, shell=True)
nlines = int(nlines.split()[0]) 

# connect to database
cnx = sqlite3.connect(out_sqlite)

# Iteratively read CSV and dump lines into the SQLite table
for i in range(0, nlines, chunksize):

    df = pd.read_csv(in_csv,  
            header=None,  # no header, define column header manually later
            nrows=chunksize, # number of rows to read at each iteration
            skiprows=i)   # skip rows that were already read

    # columns to read        
    df.columns = columns

    sql.to_sql(df, 
                name=table_name, 
                con=cnx, 
                index=False, # don't use CSV file index
                index_label='molecule_id', # use a unique column from DataFrame as index
                if_exists='append') 
cnx.close()    
 avatar Feb 06 '2015 17:02