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()
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.
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.
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.
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
On 12 sep, 17:42, Alain BARTHE <alain.barthe...@free.fr> 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
> 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