I set di dati molto grandi sono archiviati in file binari sul disco rigido. Ecco un esempio della struttura dei file:Modo efficiente per creare array di Numpy da file binari
Header File
149 Byte ASCII Header
Registrazione Avvia
4 Byte Int - Record Timestamp
esempio Avviare
2 Byte Int - Data Stream 1 Sample
2 Byte Int - Data Stream 2 Sample
2 Byte Int - Data Stream 3 Sample
2 Byte Int - Data Stream 4 Sample
fine campione
Ci sono 122,880 campioni per record e 713 record per file. Questo produce una dimensione totale di 700,910,521 byte. La frequenza di campionamento e il numero di record variano a volte, quindi devo codificare per rilevare il numero di ciascun file.
Attualmente il codice che uso per importare questi dati in array funziona così:
from time import clock
from numpy import zeros , int16 , int32 , hstack , array , savez
from struct import unpack
from os.path import getsize
start_time = clock()
file_size = getsize(input_file)
with open(input_file,'rb') as openfile:
input_data = openfile.read()
header = input_data[:149]
record_size = int(header[23:31])
number_of_records = (file_size - 149)/record_size
sample_rate = ((record_size - 4)/4)/2
time_series = zeros(0,dtype=int32)
t_series = zeros(0,dtype=int16)
x_series = zeros(0,dtype=int16)
y_series = zeros(0,dtype=int16)
z_series = zeros(0,dtype=int16)
for record in xrange(number_of_records):
time_stamp = array(unpack('<l' , input_data[ 149 + (record * record_size) : 149 + (record * record_size) + 4 ]) , dtype = int32)
unpacked_record = unpack('<' + str(sample_rate * 4) + 'h' , input_data[ 149 + (record * record_size) + 4 : 149 + ((record + 1) * record_size) ])
record_t = zeros(sample_rate , dtype=int16)
record_x = zeros(sample_rate , dtype=int16)
record_y = zeros(sample_rate , dtype=int16)
record_z = zeros(sample_rate , dtype=int16)
for sample in xrange(sample_rate):
record_t[sample] = unpacked_record[ (sample * 4) + 0 ]
record_x[sample] = unpacked_record[ (sample * 4) + 1 ]
record_y[sample] = unpacked_record[ (sample * 4) + 2 ]
record_z[sample] = unpacked_record[ (sample * 4) + 3 ]
time_series = hstack ((time_series , time_stamp))
t_series = hstack ((t_series , record_t))
x_series = hstack ((x_series , record_x))
y_series = hstack ((y_series , record_y))
z_series = hstack ((z_series , record_z))
savez(output_file, t=t_series , x=x_series ,y=y_series, z=z_series, time=time_series)
end_time = clock()
print 'Total Time',end_time - start_time,'seconds'
questo richiede attualmente circa 250 secondi per 700 file di MB, che mi sembra molto alto. C'è un modo più efficiente che potrei fare?
Soluzione Finale
Utilizzando il metodo fromfile NumPy con un costume DTYPE tagliare il tempo di esecuzione a 9 secondi, 27x più veloce rispetto al codice originale di cui sopra. Il codice finale è sotto.
from numpy import savez, dtype , fromfile
from os.path import getsize
from time import clock
start_time = clock()
file_size = getsize(input_file)
openfile = open(input_file,'rb')
header = openfile.read(149)
record_size = int(header[23:31])
number_of_records = (file_size - 149)/record_size
sample_rate = ((record_size - 4)/4)/2
record_dtype = dtype([ ('timestamp' , '<i4') , ('samples' , '<i2' , (sample_rate , 4)) ])
data = fromfile(openfile , dtype = record_dtype , count = number_of_records)
time_series = data['timestamp']
t_series = data['samples'][:,:,0].ravel()
x_series = data['samples'][:,:,1].ravel()
y_series = data['samples'][:,:,2].ravel()
z_series = data['samples'][:,:,3].ravel()
savez(output_file, t=t_series , x=x_series ,y=y_series, z=z_series, fid=time_series)
end_time = clock()
print 'It took',end_time - start_time,'seconds'
E 'dati medici? EDF? Se non sai di cosa sto parlando, non importa ...; o) In ogni caso, dai un'occhiata alla mia risposta, che uso per aprire i file binari dei dati medici in base a questa domanda: http://stackoverflow.com/q/5804052/401828. C'è una discussione interessante lì. – heltonbiker
Nessun dato è geofisico. Ho visto la tua domanda durante la ricerca prima di postare. I tuoi dati non sono nient'altro che brevi, in cui sfortunatamente ho i timestamp a 4 byte int sparsi per tutto il flusso. – Stu
Per quello che vale, molte operazioni su array di numpy strutturati sono molto più lente rispetto a normali array di numpy. Il tempo di importazione potrebbe essere più veloce, ma i calcoli potrebbero richiedere 10-100 volte di più :( –