2016-05-04 6 views
0

Ich versuche eine Binärdatei zu lesen, die aus mehreren Matrizen von Float-Zahlen besteht, die durch einen einzelnen int getrennt sind. Der Code in Matlab dies zu erreichen, ist die folgende:Mehrere Arrays in einer Binärdatei mit numpy lesen

fid1=fopen(fname1,'r'); 
for i=1:xx 
    Rstart= fread(fid1,1,'int32');  #read blank at the begining 
    ZZ1 = fread(fid1,[Nx Ny],'real*4'); #read z 
    Rend = fread(fid1,1,'int32');  #read blank at the end 
end 

Wie Sie sehen können, jede Matrixgröße ist Nx von Ny. Rstart und Rend sind nur Dummy-Werte. ZZ1 ist die Matrix mich interessiert

Ich versuche, das gleiche in Python zu tun, Sie folgendermaßen vorgehen:.

Rstart = np.fromfile(fname1,dtype='int32',count=1) 
ZZ1 = np.fromfile(fname1,dtype='float32',count=Ny1*Nx1).reshape(Ny1,Nx1) 
Rend = np.fromfile(fname1,dtype='int32',count=1) 

Dann muss ich durchlaufen die nachfolgenden Matrizen zu lesen, aber die Funktion np.fromfile behält den Zeiger in der Datei nicht bei.

Eine weitere Option:

with open(fname1,'r') as f: 
    ZZ1=np.memmap(f, dtype='float32', mode='r', offset = 4,shape=(Ny1,Nx1)) 
    plt.pcolor(ZZ1) 

Dies funktioniert gut für das erste Array, aber nicht liest die nächsten Matrizen. Irgendeine Idee wie kann ich das tun?

Ich suchte nach ähnlichen Fragen, fand aber keine passende Antwort.

Danke

+2

'numpy.fromfile' akzeptiert auch ein Dateiobjekt als erstes Argument. –

+0

Perfekt. Genau das habe ich gesucht. Wichtig ist, dass die Datei im Binärmodus geöffnet wird, z. B. 'fid = open (fname, 'rb')'. Vielen Dank! – jcdoming

Antwort

2

Der sauberste Weg, um alle Ihre Matrizen in einer einzigen vektorisiert Anweisung zu lesen ist eine Struktur Array zu verwenden:

dtype = [('start', np.int32), ('ZZ', np.float32, (Ny1, Nx1)), ('end', np.int32)] 
with open(fname1, 'rb') as fh: 
    data = np.fromfile(fh, dtype) 
print(data['ZZ']) 
+0

Schöne Antwort! Ich war mir nicht sicher, wie zusammengesetztes dtype arbeitete. Vielen Dank. – jcdoming

+0

Der Nachteil ist, dass es alle Arrays auf einmal lädt, was ich mit großen Dateien vermeiden sollte. – jcdoming

+0

Sie können immer noch einen Count-Parameter zu fromfile hinzufügen, denke ich, nein? –

1

Es gibt 2 Lösungen für dieses Problem.

Die erste:

for i in range(x): 
    ZZ1=np.memmap(fname1, dtype='float32', mode='r', offset = 4+8*i+(Nx1*Ny1)*4*i,shape=(Ny1,Nx1)) 

Wo i ist das Array, das Sie erhalten möchten.

Die zweite:

fid=open('fname','rb') 
for i in range(x): 
    Rstart = np.fromfile(fid,dtype='int32',count=1) 
    ZZ1 = np.fromfile(fid,dtype='float32',count=Ny1*Nx1).reshape(Ny1,Nx1) 
    Rend = np.fromfile(fid,dtype='int32',count=1) 

So wie morningsun darauf hinweist, kann np.fromfile ein Dateiobjekt als Argument empfangen und Spur des Zeigers zu halten. Beachten Sie, dass Sie die Datei im Binärmodus 'rb' öffnen müssen.

Verwandte Themen