Lecture fichier

Résolu
Bonjour,
J'ai un fichier csv de 3,4 Go pour plus de 11 millions de lignes, ouvrable ni avec Excel ni avec TextPad.
J'ai codé un script en Python pour le découper par million de lignes :
# Definir les répertoires de travail
cible=r"E:\Divers\exports-etalab\exports-etalab\FichiersATraiter"
os.chdir(cible)

#Découper chaque fichier à traiter par 1000000 lignes
cptrEnregLu=0
cptrFichierEcrit=1
cptrEnregEcrit=0
maxiEnregEcrit=1000000

lecture = open(r"E:\Divers\exports-etalab\exports-etalab\FichiersATraiter\declaration_avantage_2020_07_27_04_00.csv", "r", encoding='utf-8')
nomFichierEcrit=r"E:\Divers\exports-etalab\exports-etalab\Avantage" + str(cptrFichierEcrit) + ".csv"
fichierEcrit=open(nomFichierEcrit, "a", encoding='utf-8')
print("lecture = "+"avantage_2020")

for line in lecture.readlines():
cptrEnregLu=cptrEnregLu+1
fichierEcrit.write(line)
cptrEnregEcrit=cptrEnregEcrit+1

if cptrEnregLu==1:
titre=line # Memoriser titres
if cptrEnregLu % maxiEnregEcrit == 0: # Pour chaque 1 000 000 d'enreg. écrit
print(cptrFichierEcrit)
fichierEcrit.close() # fermer écriture
cptrFichierEcrit=cptrFichierEcrit+1 # ouvrir fichier d'écriture suivant et écrire titres
nomFichierEcrit=r"E:\Divers\exports-etalab\exports-etalab\Avantage" + str(cptrFichierEcrit) + ".csv"
fichierEcrit=open(nomFichierEcrit, "a", encoding='utf-8')
fichierEcrit.write(titre)

lecture.close()
fichierEcrit.close()

fin = datetime.datetime.now()
print(fin-debut)
print(cptrEnregLu)
print(cptrFichierEcrit)

Mais, le découpage prend plus de 25 minutes.
Est ce normal ? Sinon, comment diminuer le temps de traitement ?
J'ai remarqué qu'il prenait 8 bonnes minutes pour écrire le 1° fichier et 1 à 2 minute pour les suivants.
Je suppose donc que Python mémorise l'ensemble du fichier à traiter et seulement après exécute les lignes de code sur chaque ligne en mémoire.
Est ce exact ? Si oui, est ce qu'il existe une méthode ou astuce pour alléger la mémoire ?
Merci.

2 réponses

  1. Merci beaucoup
    Pour info. : le temps de traitement est passé de 25 à 6 minutes
    1. Contributeur
      bonjour, peux-tu spécifier "python" quand tu utilises les balises de code pour partager du code python?
      ton analyse est correcte: vu ce que tu as écrit, python mémorise l'ensemble du fichier.
      pour éviter cela, il faut utiliser readline pour lire une ligne à la fois, et pas readlines, qui lit toutes les lignes.
      1. Contributeur
        suggestion:
        line = lecture.readline()    
        while line:
            cptrEnregLu=cptrEnregLu+1
            fichierEcrit.write(line)
            cptrEnregEcrit=cptrEnregEcrit+1
        
            if cptrEnregLu==1:
                titre=line                                                                                                                                                                                                                                             # Memoriser titres
            if cptrEnregLu % maxiEnregEcrit  == 0:                                                                                                                                                                                             # Pour chaque 1 000 000 d'enreg. écrit
                print(cptrFichierEcrit)
                fichierEcrit.close()                                                                                                                                                                                                                             # fermer écriture 
                cptrFichierEcrit=cptrFichierEcrit+1                                                                                                                                                                                                 # ouvrir fichier d'écriture suivant et écrire titres
                nomFichierEcrit=r"E:\Divers\exports-etalab\exports-etalab\Avantage" + str(cptrFichierEcrit) + ".csv"
                fichierEcrit=open(nomFichierEcrit, "a", encoding='utf-8')
                fichierEcrit.write(titre)
            line = lecture.readline()