2011-05-13 31 views
6

Estoy tratando de leer un número de doble precisión Fortran como 1.2345D + 02 en Python, pero tengo el siguiente error:lectura formato de doble precisión FORTRAN en Python

>>> float('1.2345D+02') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: invalid literal for float(): 1.2345D+02 

Siguiendo los consejos de Python scientific notation using D instead of E, probé numpy sino también consigo el mismo error:

import numpy 
>>> numpy.float("1.2345D+02") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: invalid literal for float(): 1.2345D+02 

¿hay una solución en Python para leer esos números de doble precisión y sin apenas cambiando la 'D' a 'E'?

EDIT: reemplacé una mala sintaxis en las cadenas. Pero aún recibo errores.

+0

Solo un aviso que quizás la biblioteca de Python 'fortranformat' (en PyPI) puede ayudar. Probablemente debería revelar que soy el autor. – Brendan

Respuesta

4

¿Qué pasa con float(str.replace("D", "E"))?

Tenga en cuenta que numpy DOES admite la notación fortran: numpy.float("1.2345D+02").

Parece que tiene un propósito más profundo , quizás arrojar luz sobre él ayudaría.

+0

En general, no hay problema con la sustitución de "D" por "E". Solo quiero saber si hay una solución "nativa". Si numpy admite una notación Fortran, ¿por qué está fallando como se muestra en el ejemplo? Sí, necesito analizar grandes archivos de datos generados por Fortran y extraer algunos datos en particular. ¡Gracias! – iluvatar

+1

Porque 'numpy.float (1.2345D + 02)' sería analizado por el intérprete de python como una llamada a 'numpy.float' con' 1.2345D + 02'. '1.2345D + 02' es desconocido para el intérprete de Python, por lo que da un error. '" 1.2345D + 02 "' es una cadena, lo cual está perfectamente bien. – orlp

+0

Gracias. En realidad, fue un error tipográfico en mi ejemplo. Ya lo corrigí pero el error (otro) permanece. – iluvatar

1

La sustitución se puede hacer un poco más cuidadosa mediante el uso de una expresión regular:

import re 
re_dbl_fort = re.compile(r'(\d*\.\d+)[dD]([-+]?\d+)') 

text = 'DEW=[0.242D+03 -4.320D-06]' 
re_dbl_fort.sub(r'\1E\2', text) 
# DEW=[0.242E+03 -4.320E-06] 

O si usted tiene una lista de cadenas (líneas) leer de un archivo usando readlines():

lines = ['REPORT CARD\n', 'GRADE: D+ (1.3D+00/4.0D+00)\n'] 
for ln, line in enumerate(lines): 
    res = re_dbl_fort.sub(r'\1E\2', line) 
    if line != res: 
     lines[ln] = res 
# ['REPORT CARD\n', 'GRADE: D+ (1.3E+00/4.0E+00)\n']