The accepted answer is helpful, but does not support negative values (-0.3299880
is converted to e-0.3299880
) or 2-digit exponents (0.3299880E+10
is converted to 0.3299880Ee10
), which both do not make sense and would result in nan
values in the numpy array.
Also, the number of columns in the file to read is hard-coded (it is 3 in this case).
It can be addressed as follows:
import re
import numpy as np
def read_fortran_data_file(file):
# count the columns in the first row of data
number_columns = np.genfromtxt(file, max_rows=1).shape[0]
c = lambda s: float(re.sub(r"(\d)([\+\-])(\d)", r"\1E\2\3", s.decode()))
# actually load the content of our file
data = np.genfromtxt(file,
converters=dict(zip(range(number_columns), [c] * number_columns)),)
Testing
np.genfromtext
accepts filenames or arrays of strings as input.
For the demonstration I'll use the latter, but the above function works fine with filenames as input.
strings = [
"0.3299880-104 0.3299880E+10 0.3299880 0.3299880+104 0.3299880E-10 -0.3299880"
]
read_fortran_data_file(strings)
## array([ 3.29988e-105, 3.29988e+009, 3.29988e-001, 3.29988e+103,
## 3.29988e-011, -3.29988e-001])
Note on NaN values:
When using np.genfromtxt
, one must be careful with NaN values that would replace numbers that were not read properly, e.g. using the following assertion:
assert np.count_nonzero(np.isnan(data))==0, "data contains nan values"