Comment importer et lire plusieurs CSV par blocs lorsque nous avons plusieurs fichiers csv et que la taille totale de tous les csv est d'environ 20 Go?
Je ne veux pas utiliser Spark
comme je le souhaite utiliser un modèle dans SkLearn donc je veux la solution dans Pandas
lui-même.
Mon code est:
allFiles = glob.glob(os.path.join(path, "*.csv")) df = pd.concat((pd.read_csv(f,sep=",",chunksize=10000) for f in allFiles)) df.reset_index(drop=True, inplace=True)
Mais c'est échec car la taille totale de tout le csv dans mon chemin est de 17 Go.
Je veux le lire par morceaux mais j'obtiens une erreur si j'essaye comme ceci:
allFiles = glob.glob(os.path.join(path, "*.csv")) df = pd.concat((pd.read_csv(f,sep=",") for f in allFiles)) df.reset_index(drop=True, inplace=True)
3 Réponses :
pour lire un gros fichier csv, vous pouvez utiliser chunksize mais dans ce cas, vous devez utiliser un itérateur comme celui-ci:
listfile = ['file1,'file2] dfx = pd.DataFrame() def process(d): #dfx=dfx.append(d) or dfx = pd.concat(dfx, d) #other coding for f in listfile: for df in pd.read_csv(f, sep=',', iterator=True, chunksize=10000): process(df)
vous devez concater ou ajouter chaque morceau
ou vous pouvez le faire:
df = pd.read_csv('file.csv',, sep=',', iterator=True, chunksize=10000) for chunk in df: process(chunk)
pour lire plusieurs fichiers: par exemple
for df in pd.read_csv('file.csv', sep=',', iterator=True, chunksize=10000): process(df)
après avoir beaucoup de fichiers vous pouvez utiliser DASK ou Pool de la bibliothèque multiprocesseur pour lancer beaucoup de processus de lecture
Quoi qu'il en soit, soit vous avez assez de mémoire, soit vous perdez du temps
cela fonctionne bien si j'essaie de lire 1 csv. Mais dans mon cas, j'ai un tas de csv dans mon dossier. Donc read_csv ("file.csv") utilise juste 1 fichier ici mais j'ai un dossier avec beaucoup de csv Je suis c'est pourquoi les concaténer dans mon exemple de code
@pythonNinja je vous suggère de supprimer un maximum de données inutilisées pour votre machine learning..J'ai modifié mon programme pour lire plusieurs fichiers.
merci mais au moment où j'essaye de concater les données, j'obtiens la même erreur
C'est une question intéressante. Je n'ai pas essayé cela, mais je pense que le code ressemblerait à quelque chose comme le script ci-dessous.
import pandas as pd import csv import glob import os #os.chdir("C:\\your_path\\") results = pd.DataFrame([]) filelist = glob.glob("C:\\your_path\\*.csv") #dfList=[] for filename in filelist: print(filename) namedf = pd.read_csv(filename, skiprows=0, index_col=0) results = results.append(namedf) results.to_csv('C:\\your_path\\Combinefile.csv') chunksize = 10 ** 6 for chunk in pd.read_csv('C:\\your_path\\Combinefile.csv', chunksize=chunksize): process(chunk)
Vous pourriez peut-être tout charger en mémoire et le traiter directement, mais cela prendrait probablement beaucoup plus de temps pour tout traiter.
Une façon de le faire est de fragmenter la trame de données avec pd.read_csv (fichier, chunksize = chunksize), puis si le dernier morceau que vous lisez est plus court que la taille du bloc, enregistrez le bit supplémentaire puis ajoutez-le au premier fichier du morceau suivant.
Mais assurez-vous de lire un premier morceau plus petit du fichier suivant afin qu'il corresponde à la taille totale du morceau.
def chunk_from_files(dir, master_chunksize): ''' Provided a directory, loops through files and chunks out dataframes. :param dir: Directory to csv files. :param master_chunksize: Size of chunk to output. :return: Dataframes with master_chunksize chunk. ''' files = os.listdir(dir) chunksize = master_chunksize extra_chunk = None # Initialize the extra chunk. for file in files: csv_file = os.path.join(dir, file) # Alter chunksize if extra chunk is not None. if extra_chunk is not None: chunksize = master_chunksize - extra_chunk.shape[0] for chunk in pd.read_csv(csv_file, chunksize=chunksize): if extra_chunk is not None: # Concatenate last small chunk of previous file with altered first chunk of next file. chunk = pd.concat([chunk, extra_chunk]) extra_chunk = None chunksize = master_chunksize # Reset chunksize. elif chunk.shape[0] < chunksize: # If last chunk is less than chunk size, set is as the extra bit. extra_chunk = chunk break yield chunk
Avez-vous essayé
df = pd.concat ([pd.read_csv (f, sep = ",", chunksize = 10000) pour f dans tous les fichiers])
. C'est à dire. avec des crochets? Je pense que les supports normaux vous donnent un générateur ...@mortysporty non n'a pas aidé. Même erreur
En regardant la documentation de
pd.read_csv
, il semble que la spécification de l'argumentchunksize
fait que l'appel de méthode renvoie un objetTextFileReader
(plutôt qu'un dataframe) qui doit être répété.Si vous n'avez pas la RAM nécessaire pour contenir le résultat de tous les morceaux, peu importe que vous le lisiez par morceaux ou non ...
@JonClements - J'ai la RAM, c'est juste que cela rend ce processus de lecture très lent et réduit les performances
Pouvez-vous fournir vos exigences matérielles? Quelle est la taille de votre RAM? Combien de CPU / GPU avez-vous?