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.
3 Réponses :
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)
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")
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)