Ihnen eine Vorstellung davon zu geben, was ich in meiner zweiten Bemerkung gemeint, machte ich eine Mock-up:
testwrite.f90, mit gfortran zusammengestellt 4.8.4: Es schreibt grundsätzlich eine unformatierte, sequentielle Datei mit dem Arrays Sie haben angegeben (nur viel kleiner, um sie mit dem Auge vergleichen zu können), gefüllt mit beliebigen Daten. Es druckt auch die Arrays.
implicit none
integer nS, nT, i ,j
parameter (nS = 10)
parameter (nT = 3)
real(8) wn_arr(nS) ! wavenumber [cm^-1]
real(8) temp_arr(nT) ! temperature [K]
real(8) abs_arr(nS,nT) ! absorption coefficient [cm^-1/amagat^2]
wn_arr = (/ (i, i=1,nS) /)
temp_arr = (/ (270+i, i=1,nT) /)
abs_arr = reshape((/ ((10*j+i, i=1,nS), j=1,nT) /), (/nS, nT/))
print*, wn_arr
print*, '-----------------'
print*, temp_arr
print*, '-----------------'
print*, abs_arr
print*, '-----------------'
print*, 'abs_arr(5,3) = ', abs_arr(5,3)
open(33,file='test.out',form='unformatted')
write(33) wn_arr
write(33) temp_arr
write(33) abs_arr
close(33)
end
testread.py, getestet mit Python 2.7.6, liest dann die oben geschriebene Datei und druckt auch die Arrays. Für mich ist die Ausgabe beider Programme gleich. YMMV.
import numpy as np
rec_delim = 4 # This value depends on the Fortran compiler
nS = 10
nT = 3
with open('test.out', 'rb') as infile:
infile.seek(rec_delim, 1) # begin record
wn_arr = np.fromfile(file=infile, dtype=np.float64, count=nS)
infile.seek(rec_delim, 1) # end record
infile.seek(rec_delim, 1) # begin record
temp_arr = np.fromfile(file=infile, dtype=np.float64, count=nT)
infile.seek(rec_delim, 1) # end record
infile.seek(rec_delim, 1) # begin record
abs_arr = np.fromfile(file=infile,
dtype=np.float64).reshape((nS, nT), order='F')
infile.seek(rec_delim, 1) # end record
print(wn_arr)
print(temp_arr)
print(abs_arr)
# The array has the same shape, but Fortran starts index (per default at least)
# at 1 and Python at 0:
print('abs_arr(5,3) = ' + str(abs_arr[4,2]))
Kurze Erklärung: Ich öffne die Datei in einer mit Block (guten Praxis in Python) und dann trete ich durch die Datei, mit dem Wissen, wie die Datei geschrieben wird. Dies macht es unportabel. infile.seek (4, 1) verschiebt den Lesezeiger von Python um 4 Bytes von der aktuellen Position (die Option 1), weil ich weiß, dass die Datei mit einem 4 Zeichen langen Marker beginnt (gfortran) .
Dann benutze ich numpy.fromfile, um count = 10 Werte von float64 zu lesen, welches das Wellenzahl-Array ist.
Als nächstes muss ich die End-Aufzeichnung überspringen und Marker starten. Dies könnte natürlich auch von infile.seel (8, 1) übernommen werden.
Dann lese ich das Temperatur-Array, überspringe End-Record und beginne die Marker erneut und lese das 2D-Array. Die Daten in der Datei wissen nicht, dass es 2D ist, also muss ich es umformen, indem ich die Fortran-Reihenfolge verwende. Die letzte .seek() ist falsch, ich wollte nur die Struktur hervorheben.
Ich wiederhole dringend, dass Sie kein größeres System auf Code wie diesem bauen. Es ist in Ordnung für eine einmalige, aber schrecklich für etwas, das Sie wieder verwenden oder teilen müssen.
Fortran unformatierte Dateien sind ein tragbarer Albtraum. Im Allgemeinen können Sie nur erwarten, dass sie funktionieren, wenn Sie mit demselben Compiler auf derselben Hardware lesen/schreiben (da die Record-Begrenzer nicht standardisiert sind). Es sieht so aus, als ob "scipy.io.FortanFile" davon ausgeht, dass die Datensätze mit 'gfortran' auf einer' x86_64' Architektur geschrieben wurden. Ist das der Compiler/Architektur, die Sie verwenden? – mgilson
Die Antwort hängt davon ab, wie oft Sie diese Datei lesen müssen und wie tragbar das ganze System sein soll.Ihr größtes Problem ist, wie mgilson bereits gesagt hat, dass die Datei in einem unformatierten SEQUENTIAL-Format vorliegt, das nicht nur die Daten, sondern auch eine Anfangs- und Endaufzeichnung um jeden Datensatz speichert (= etwa jede geschriebene Variable), die Größe davon ist Compiler abhängig. Wenn Sie nur die Datei lesen und sich nicht um die Portabilität kümmern möchten, versuchen Sie, den Parsing-Code selbst zu schreiben. Ich habe keine Erfahrung mit der scipy.io.FortranFile-Methode, aber ihre Optionen scheinen begrenzt und wenn es nicht funktioniert ... – StefanS
Ohne die Datei ist es schwer, Ihnen mit Code zu helfen, aber ich habe unformatiert gelesen (direkter Zugriff, nicht sequentiell) Fortran-Dateien mit numpy.fromfile. Sie müssen die file.seek() -Methode verwenden, um die Marker für Anfangs- und Endaufzeichnung zu überspringen und mit ihrer Größe zu spielen, bis Sie die richtige getroffen haben (verwenden Sie 4 oder 1 Byte zum Starten, diese sollten die gebräuchlichsten sein) Einsen). – StefanS