Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Optimisation

22 réponses
Avatar
pil91
Bonjour, j'ai besoin de transformer en format csv d=E9limit=E9, des
fichiers fixes.
Le probl=E8me c'est que ces fichiers peuvent =EAtre tr=E8s gros, plusieurs
millions de lignes et plusieurs milliers de caract=E8res par ligne.
J'ai donc =E9crit ce code sous windows en Python 2.5.2, qui, je pense
pourrait =EAtre bien optimis=E9.
Merci d'avance pour vos suggestions.

=3D=3D=3D=3D=3D=3D=3D=3D=3D
# _*_ coding: utf8 _*_
#!/usr/bin/env python
# Auteur : Philippe Lotton
# Date de cr=E9ation:

import sys
import datetime
if __name__ =3D=3D '__main__':
args =3D sys.argv[1:]
if len(args) =3D=3D 2: # 2 param=E8tres obligatoires
fic_entree =3D args[0] # Fichier source
fic_format =3D args[1] #Fichier format
else:
print '''Vous devez passez 2 arguments, le fichier source et
le fichier param=E8tre
ex: csv.py MonFic.txt MonFormat.txt
Le fichier source doit avoir des enregistrements de longueurs
fixes.
Le fichier format doit =E8tre de la forme: position , longueur
<rc>,
autant de ligne que de champs dans le fichier source.
'''
exit()
print datetime.datetime.now().time()
fic_param =3D open('format.txt', "r") # Lecture du fichier
param=E8tre
format =3D fic_param.readlines() # Cr=E9ation tableaux
des param=E8tres
fic_param.close()

fic_out =3D open('csv.txt', 'w') #Ouverture fichier de sortie

fic_source =3D open(fic_entree, 'r') # Lecture du fichier
source
while 1: #
ligne_source =3D fic_source.readline()
if ligne_source =3D=3D'':
break
else :
ligne_cible =3D '' # Ligne de sortie =E9crite dans
le fichier
for j in format:
params =3D j.split(',') #Cr=E9ation d'un
tableau de param=E8tres
pos1 =3D int(params[0])-1 #Position 1
pos2 =3D pos1 + int(params[1]) #Position 2
temp =3D ligne_source[ pos1:pos2]
ligne_cible =3D ligne_cible + temp + ',' #
Concat=E9nation
ligne_cible =3D ligne_cible[0:-1]
fic_out.write(ligne_cible + "\n")
ligne_cible =3D ''
fic_source.close()
fic_out.close()
print datetime.datetime.now().time()
exit()

2 réponses

1 2 3
Avatar
Alain BARTHE
Alain BARTHE a écrit :
Bruno Desthuilliers a écrit :
Alain BARTHE a écrit :
(snip)
Je pense que tu pourrais aussi utiliser le module struct, qui semble
mieux adapté pour ton problème.



doh :(

C'est ça le problème avec Python : y a tellement de trucs dans la
biblio standard qu'on oublie fréquemment de vérifier si y a pas déjà
une bonne soluce quelque part...

Principe :
- définir une format décrivant la structure de tes enregistrements:

Exemple : Si ton enregistrement contient :
nom 30 caractères
prenom 20 caractères
tel 10 entiers








Je me suis planté dans la syntaxe du format : 10i indique un tableau de
10 entiers codés en binaire selon la plateforme (4 octets sur ma machine)

On peut utiliser hHiIlL (pour short, int, long signés ou non) et même
précéder de @=<> pour préciser les types de plateformes et d'endianess.


Tu crées un format = "30s20s10i"

import struct

format = "30s20s10i"
size = struct.calcsize (format)

in = open ("fichier.dat", "r")
out = open ("fichier.csv", "w")

while f:
data = in.read (size)



Attention, s'il y a des newlines en fin d'enregistrement, il faut en
tenir compte dans la taille (et probablement dans le struct), en
tenant compte des problèmes de portabilité entre plateformes pour le
format des newlines.




On peut ajouter le motif x (padding) dans le format pour prendre en
compte le n ou même ignorer un champ dont on n'a pas besoin.

nom, prenom, tel = struct.unpack (format, data)

print >> out, "%s,%s,%d;", % (nom,prenom,tel)

in.close()
out.close()



(snip)
Par contre, je ne sais pas si ce sera plus efficace.



<OP>
Pil, si tu tentes cette solution, je veux bien savoir le résultat (si
ça fonctionne pour ton cas, et si oui si c'est plus performant).
</OP>



Concernant le fonctionnement, je pense que ça correspond bien avec son
problème. Je n'ai pas pu tester réellement car je n'avais pas le temps
de me créer un fichier de test, mais le module semble fait pour.

Pour les perf, j'espère que ça doit être meilleur, le module semble être
un .so dont probablement être écrit en C et la découpe des divers champs
devrait être plus efficace qu'avec du code Python.

A confirmer quand même.


Avatar
pil91
On 12 sep, 17:42, Alain BARTHE wrote:
Alain BARTHE a écrit :



> Bruno Desthuilliers a écrit :
>> Alain BARTHE a écrit :
>> (snip)
>>> Je pense que tu pourrais aussi utiliser le module struct, qui semble
>>> mieux adapté pour ton problème.

>> doh :(

>> C'est ça le problème avec Python : y a tellement de trucs dans la
>> biblio standard qu'on oublie fréquemment de vérifier si y a pas d éjà
>> une bonne soluce quelque part...

>>> Principe :
>>> - définir une format décrivant la structure de tes enregistrement s:

>>> Exemple : Si ton enregistrement contient :
>>>     nom     30 caractères
>>>     prenom    20 caractères
>>>     tel    10 entiers

Je me suis planté dans la syntaxe du format : 10i indique un tableau de
10 entiers codés en binaire selon la plateforme (4 octets sur ma machin e)

On peut utiliser hHiIlL (pour short, int, long signés ou non) et même
précéder de @=<> pour préciser les types de plateformes et d'endi aness.

>>> Tu crées un format = "30s20s10i"

>>> import struct

>>> format = "30s20s10i"
>>> size = struct.calcsize (format)

>>> in = open ("fichier.dat", "r")
>>> out = open ("fichier.csv", "w")

>>> while f:
>>>     data = in.read (size)

>> Attention, s'il y a des newlines en fin d'enregistrement, il faut en
>> tenir compte dans la taille (et probablement dans le struct), en
>> tenant compte des problèmes de portabilité entre plateformes pour le
>> format des newlines.

> On peut ajouter le motif x (padding) dans le format pour prendre en
> compte le n ou même ignorer un champ dont on n'a pas besoin.

>>>     nom, prenom, tel = struct.unpack (format, data)

>>>     print >> out, "%s,%s,%d;", % (nom,prenom,tel)

>>> in.close()
>>> out.close()

>> (snip)
>>> Par contre, je ne sais pas si ce sera plus efficace.

>> <OP>
>> Pil, si tu tentes cette solution, je veux bien savoir le résultat (s i
>> ça fonctionne pour ton cas, et si oui si c'est plus performant).
>> </OP>

> Concernant le fonctionnement, je pense que ça correspond bien avec so n
> problème. Je n'ai pas pu tester réellement car je n'avais pas le te mps
> de me créer un fichier de test, mais le module semble fait pour.

> Pour les perf, j'espère que ça doit être meilleur, le module semb le être
> un .so dont probablement être écrit en C et la découpe des divers champs
> devrait être plus efficace qu'avec du code Python.

> A confirmer quand même.



Juste un msg pous vous dire que je suis le fil, que vous enrichissez.
Je n'ai pas eu beaucoup de temps, mais je reprends tout ça la semaine
prochaine et je vous fait remonter les résultats.
Bon week-end
1 2 3