Dividir archivos realmente grandes en archivos más pequeños en Python – Demasiados archivos abiertos

Tengo un archivo csv muy grande (cerca de un Terabyte) que quiero dividir en archivos csv más pequeños, según la información de cada fila.

Ya que no hay forma de hacerlo en la memoria, mi enfoque previsto era leer cada línea, decidir en qué archivo debería ir y agregarla allí. Sin embargo, esto lleva mucho tiempo, ya que abrir y cerrar lleva demasiado tiempo.

Mi segundo enfoque fue mantener abiertos todos los archivos (alrededor de 3000); sin embargo, esto no funciona porque no puedo tener tantos archivos abiertos en paralelo.

Detalles adicionales según lo solicitado: el archivo .csv contiene datos de mapas que necesito para acceder a la región. Por lo tanto, planeo agruparlo en archivos que cubren diferentes cuadros de límite. Dado que se trata de datos sin clasificar, tengo que procesar el lat / lon de cada fila, asignarle el archivo correcto y adjuntar la fila al archivo.

¿Cuál sería un enfoque de trabajo (rápido, idealmente) para eso?

Esto puede ser algo así como un método hacky pero requeriría pandas y hacer algunos apéndices por lotes. Esto resolverá el problema de tener que abrir y cerrar archivos durante el procesamiento de cada fila. Voy a suponer que la forma en que asignas las filas a tus CSV se basa en algún valor de una columna en tu CSV grande.

 import pandas as pd import os df_chunked = pd.read_csv("myLarge.csv", chunksize=30000) # you can alter the chunksize for chunk in df_chunked: uniques = chunk['col'].unique().tolist() for val in uniques: df_to_write = chunk[chunk['col'] == val] if os.path.isfile('small_{}.csv'.format(val)): # check if file already exists df_to_write.to_csv('small_{}.csv'.format(val), mode='a', index=False, header=False) else: df_to_write.to_csv('small_{}.csv'.format(val), index=False) 

Aunque estoy de acuerdo con los comentarios de que conocer los detalles del archivo sería esencial para proporcionar una respuesta de trabajo real, tuve un problema similar y lo resolví utilizando pandas.

El método .read_csv de pandas utilizará el lector csv para leer solo parcialmente los archivos csv sin cargar todo el archivo en la memoria. Lo mejor es hacer una prueba y error y ver cuántas filas a la vez puede admitir su sistema

 import pandas as pd num_rows = 6000 # or some value which depends on system memory NewDf1 =pd.DataFrame() NewDf2 = pd.DataFrame() for i in range(start,stop,num_rows): rawdata_df = pd.read_csv(filename,skiprows=range(1,i),nrows=num_rows) NewDf1.append(rawdata_df[rawdata_df.iloc[1]>0],ignore_index=True) NewDf2.append(rawdata_df[rawdata_df.iloc[2]>0],ignore_index=True) 

Al final, dependiendo de la memoria real del sistema y la estructura de los archivos (debido a que el tamaño del dataframe depende también del número de columnas y la estructura de los datos), puede guardar los marcos de datos separados en csvs separados.

  if len(NewDf1) > toolarge: NewDf1.to_csv('newdf1Filename.csv')