2016-05-09 9 views
2

Ich habe eine große Binärdatei, die ich in einem Array lesen möchte. Das Format der binären Dateien ist:Geschwindigkeit beim Lesen einer Binärdatei verbessern

  • gibt es ein extra Daten von 4 Bytes am Anfang und am Ende jeder Zeile, die ich nicht verwenden;
  • zwischen I 8 Bytes haben Werte

ich es so mache:

 # nlines - number of row in the binary file 
     # ncols - number of values to read from a row 

     fidbin=open('toto.mda' ,'rb'); #open this file 
     temp = fidbin.read(4) #skip the first 4 bytes 
     nvalues = nlines * ncols # Total number of values 

     array=np.zeros(nvalues,dtype=np.float) 

     #read ncols values per line and skip the useless data at the end 
     for c in range(int(nlines)): #read the nlines of the *.mda file 
      matrix = np.fromfile(fidbin, np.float64,count=int(ncols)) #read all the values from one row 
      Indice_start = c*ncols 
      array[Indice_start:Indice_start+ncols]=matrix 
      fidbin.seek(fidbin.tell() + 8) #fid.tell() the actual read position + skip bytes (4 at the end of the line + 4 at the beginning of the second line) 
     fidbin.close() 

Es funktioniert gut, aber das Problem ist, dass für großen Binärdatei sehr langsam ist. Gibt es eine Möglichkeit, die Lesegeschwindigkeit der Binärdatei zu erhöhen?

+0

Welche Python-Version verwenden Sie? – niemmi

Antwort

2

Sie können einen strukturierten Datentyp verwenden und die Datei mit einem einzelnen Aufruf an numpy.fromfile lesen. Zum Beispiel hat meine Datei qaz.mda fünf Spalten mit Gleitkommawerten zwischen den vier Byte-Markierungen am Anfang und Ende jeder Zeile. So können Sie einen strukturierten Datentyp erstellen und die Daten lesen.

Zuerst einen Datentyp erstellen, die das Format jeder Zeile übereinstimmt:

In [547]: ncols = 5 

In [548]: dt = np.dtype([('pre', np.int32), ('data', np.float64, ncols), ('post', np.int32)]) 

Lesen Sie die Datei in ein strukturiertes Array:

In [549]: a = np.fromfile("qaz.mda", dtype=dt) 

In [550]: a 
Out[550]: 
array([(1, [0.0, 1.0, 2.0, 3.0, 4.0], 0), 
     (2, [5.0, 6.0, 7.0, 8.0, 9.0], 0), 
     (3, [10.0, 11.0, 12.0, 13.0, 14.0], 0), 
     (4, [15.0, 16.0, 17.0, 18.0, 19.0], 0), 
     (5, [20.0, 21.0, 22.0, 23.0, 24.0], 0)], 
     dtype=[('pre', '<i4'), ('data', '<f8', (5,)), ('post', '<i4')]) 

nur die Daten herausziehen, die wir wollen:

In [551]: data = a['data'] 

In [552]: data 
Out[552]: 
array([[ 0., 1., 2., 3., 4.], 
     [ 5., 6., 7., 8., 9.], 
     [ 10., 11., 12., 13., 14.], 
     [ 15., 16., 17., 18., 19.], 
     [ 20., 21., 22., 23., 24.]]) 

Sie könnten auch mit numpy.memmap experimentieren, um zu sehen, ob es die Leistung verbessert:

In [563]: a = np.memmap("qaz.mda", dtype=dt) 

In [564]: a 
Out[564]: 
memmap([(1, [0.0, 1.0, 2.0, 3.0, 4.0], 0), 
     (2, [5.0, 6.0, 7.0, 8.0, 9.0], 0), 
     (3, [10.0, 11.0, 12.0, 13.0, 14.0], 0), 
     (4, [15.0, 16.0, 17.0, 18.0, 19.0], 0), 
     (5, [20.0, 21.0, 22.0, 23.0, 24.0], 0)], 
     dtype=[('pre', '<i4'), ('data', '<f8', (5,)), ('post', '<i4')]) 

In [565]: data = a['data'] 

In [566]: data 
Out[566]: 
memmap([[ 0., 1., 2., 3., 4.], 
     [ 5., 6., 7., 8., 9.], 
     [ 10., 11., 12., 13., 14.], 
     [ 15., 16., 17., 18., 19.], 
     [ 20., 21., 22., 23., 24.]]) 

Beachten Sie, dass data oben ist immer noch ein Memory-Mapped-Array. Um sicherzustellen, dass die Daten in ein Array in dem Speicher kopiert werden, kann numpy.copy verwendet werden:

In [567]: data = np.copy(a['data']) 

In [568]: data 
Out[568]: 
array([[ 0., 1., 2., 3., 4.], 
     [ 5., 6., 7., 8., 9.], 
     [ 10., 11., 12., 13., 14.], 
     [ 15., 16., 17., 18., 19.], 
     [ 20., 21., 22., 23., 24.]]) 

Ob die notwendig ist, hängt davon ab, wie Sie das Array in dem Rest Ihres Codes verwenden.

+0

Vielen Dank für Ihre Antwort !!! .... die Geschwindigkeitssteigerung ist erstaunlich von 16 Sekunden auf 0,18 Sekunden –