Lecture fichier [Résolu]

Signaler
-
 Gerard -
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

Messages postés
12654
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
17 octobre 2020
702
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.
Messages postés
12654
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
17 octobre 2020
702
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()
Merci beaucoup
Pour info. : le temps de traitement est passé de 25 à 6 minutes