1
votes

Besoin d'extraire des données tabulaires d'un fichier texte en python3

J'ai la sortie d'un programme de chimie quantique à partir duquel je souhaite extraire des données tabulaires pour les entrer dans un port Python d'un programme FORTRAN que j'ai écrit il y a environ 25 ans.

Certains des fichiers de sortie sont assez longs, autant comme 6000 lignes ce qui empêche l'utilisation d'une feuille de calcul pour le traitement.

Une table typique est de la forme:

                             CARTESIAN COORDINATES

   1    C        0.011987266    -0.003842185     0.006578784
   2    H        1.097152909    -0.003956163     0.013339310
   3    H       -0.349612312     1.019316731     0.001903075
   4    H       -0.344276148    -0.517463019    -0.880495291
   5    H       -0.355315644    -0.513266496     0.891567896

Je ne demande pas à quelqu'un d'écrire le code Python pour moi, mais plutôt de m'en donner guidage dans le labyrinthe du code disponible.


0 commentaires

3 Réponses :


0
votes

Je vous suggère de regarder np. genfromtxt . L'extrait de code suivant lira les données d'exemple de votre question stockées dans un fichier appelé data.txt.

 [(1, b'C',  0.01198727, -0.00384219,  0.00657878)
 (2, b'H',  1.09715291, -0.00395616,  0.01333931)
 (3, b'H', -0.34961231,  1.01931673,  0.00190307)
 (4, b'H', -0.34427615, -0.51746302, -0.88049529)
 (5, b'H', -0.35531564, -0.5132665 ,  0.8915679 )]

Output

import numpy as np
data = np.genfromtxt('data.txt', skip_header=2, dtype=[('id', 'i8'),('label','S1'),('x','f8'),('y','f8'),('z','f8')])
print(data)


0 commentaires

0
votes

Les expressions régulières sont construites pour extraire des éléments des données - si vos tables sont toujours bien définies, vous pouvez les extraire en utilisant fe: https://regex101.com/r/QUT2o3/2

1    C        0.011987266    -0.003842185     0.006578784
2    H        1.097152909    -0.003956163     0.013339310
3    H       -0.349612312     1.019316731     0.001903075
4    H       -0.344276148    -0.517463019    -0.880495291
5    H       -0.355315644    -0.513266496     0.891567896

1    C        0.011987266    -0.003842185     0.006578784
2    H        1.097152909    -0.003956163     0.013339310
3    H       -0.349612312     1.019316731     0.001903075
4    H       -0.344276148    -0.517463019    -0.880495291
5    H       -0.355315644    -0.513266496     0.891567896

1    C        0.011987266    -0.003842185     0.006578784
2    H        1.097152909    -0.003956163     0.013339310
3    H       -0.349612312     1.019316731     0.001903075
4    H       -0.344276148    -0.517463019    -0.880495291
5    H       -0.355315644    -0.513266496     0.891567896

Apply regex:

matches = re.findall(regex, test_str, re.MULTILINE | re.DOTALL)
for m in matches:
    print('\n'.join(x.strip() for x in m.splitlines()))

Résultat:

import re

regex = r"(\d+ +\w+ (?: +-?\d+\.\d+){3}.+?(?:\n|\Z){2})+"

test_str = ("                      CARTESIAN COORDINATES\n\n"
    "   1    C        0.011987266    -0.003842185     0.006578784\n"
    "   2    H        1.097152909    -0.003956163     0.013339310\n"
    "   3    H       -0.349612312     1.019316731     0.001903075\n"
    "   4    H       -0.344276148    -0.517463019    -0.880495291\n"
    "   5    H       -0.355315644    -0.513266496     0.891567896\n\n\n\n"
    "                      CARTESIAN COORDINATES\n\n"
    "   1    C        0.011987266    -0.003842185     0.006578784\n"
    "   2    H        1.097152909    -0.003956163     0.013339310\n"
    "   3    H       -0.349612312     1.019316731     0.001903075\n"
    "   4    H       -0.344276148    -0.517463019    -0.880495291\n"
    "   5    H       -0.355315644    -0.513266496     0.891567896\n\n\n"
    "                      CARTESIAN COORDINATES\n\n"
    "   1    C        0.011987266    -0.003842185     0.006578784\n"
    "   2    H        1.097152909    -0.003956163     0.013339310\n"
    "   3    H       -0.349612312     1.019316731     0.001903075\n"
    "   4    H       -0.344276148    -0.517463019    -0.880495291\n"
    "   5    H       -0.355315644    -0.513266496     0.891567896")


0 commentaires

1
votes

J'utiliserais readlines et split.

1 C 0.011987266 -0.003842185 0.006578784
2 H 1.097152909 -0.003956163 0.01333931
3 H -0.349612312 1.019316731 0.001903075
4 H -0.344276148 -0.517463019 -0.880495291
5 H -0.355315644 -0.513266496 0.891567896

Résultat:

cc = 'CARTESIAN_COORDINATES.txt'

with open(cc) as data:
    lines = data.readlines()[2:] # skip first two lines
    for line in lines:
        ls = line.split()
        a, b, c, d, e = int(ls[0]), ls[1], float(ls[2]), float(ls[3]), float(ls[4])
        print(a, b, c, d, e)


0 commentaires