2013-07-10 9 views
7

Nel mio programma sto lavorando con vari array numpy di varie dimensioni. Ho bisogno di memorizzarli in file XML per un uso successivo. Non li ho scritti su file binari, quindi ho tutti i miei dati in un posto (il file XML) e non sparsi in 200 file.Archiviazione e caricamento di array numpy come file

Così ho provato a usare il metodo array_str() di numpy per trasformare un array in una stringa. L'XML risultante è simile al seguente:

-<Test date="2013-07-10-17:19"> 
    <Neurons>5</Neurons> 
    <Errors>[7.7642140551985428e-06, 7.7639131137987232e-06]</Errors> 
    <Iterations>5000</Iterations> 
    <Weights1>[[ 0.99845902 -0.70780512 0.26981375 -0.6077122 0.09639695] [ 0.61856711 -0.74684913 0.20099992 0.99725171 -0.41826754] [ 0.79964397 0.56620812 -0.64055346 -0.50572793 -0.50100635]]</Weights1> 
    <Weights2>[[-0.1851452 -0.22036027] [ 0.19293429 -0.1374252 ] [-0.27638478 -0.38660974] [ 0.30441414 -0.01531598] [-0.02478953 0.01823584]]</Weights2> 
</Test> 

I pesi sono i valori che voglio conservare. Ora il problema è che fromstring di NumPy() metodo non può ricaricare questi a quanto pare ... ottengo "ValueError: formato stringa deve essere un multiplo di dimensioni dell'elemento"

le ho scritte con "np.array_str (W1) "e prova a leggerli con" np.fromstring (w_str1) ". Apparentemente il risultato è solo un array 1D anche se funziona, quindi devo ripristinare la forma manualmente. Ugh, questo è già un dolore dato che dovrò anche memorizzarlo in qualche modo.

Qual è il modo migliore per farlo correttamente? Preferibilmente uno che salva anche la forma e il tipo di dati del mio array senza la manutenzione manuale per ogni piccola cosa.

risposta

11

Numpy fornisce un modo semplice per memorizzare molti array in un file compresso:

a = np.arange(10) 
b = np.arange(10) 
np.savez_compressed('file.npz', a=a, b=b) 

È anche possibile modificare i nomi degli array durante il salvataggio, facendo ad esempio: np.savez_compressed('file.npz', newa=a, newb=b).

Per leggere l'utilizzo file salvato np.load(), che restituisce un'istanza NpzFile che funziona come un dizionario:

loaded = np.load('file.npz') 

Per caricare le matrici:

a_loaded = loaded['a'] 
b_loaded = loaded['b'] 

o:

from operator import itemgetter 
g = itemgetter('a', 'b') 
a_loaded, b_loaded = g(np.load('file.npz')) 
+0

Grazie non è esattamente quello che avevo in mente (questo crea ancora tonnellate di file esterni), ma questa soluzione è estremamente semplice almeno. Posso associare file NPZ ai miei dati XML utilizzando le date come nomi di file. – user2323596

+2

Almeno qui è possibile memorizzare molti array in un solo file e l'accesso può essere fatto in seguito utilizzando i tasti del dizionario come date, ad esempio: 'np.savez_compressed ('all.npz', d2013_12_29 = a, d2013_12_30 = b , d2013_12_31 = c) ', puoi includere tutte le date che desideri qui ... –

3

Sfortunatamente non esiste un modo semplice per leggere l'output corrente in numpy. L'uscita non sarà così bello sul file XML, ma si potrebbe creare una versione leggibile dei vostri array come segue:

>>> import cStringIO 
>>> a = np.array([[ 0.99845902, -0.70780512, 0.26981375, -0.6077122, 0.09639695], [ 0.61856711, -0.74684913, 0.20099992, 0.99725171, -0.41826754], [ 0.79964397, 0.56620812, -0.64055346, -0.50572793, -0.50100635]]) 
>>> out_f = cStringIO.StringIO() 
>>> np.savetxt(out_f, a, delimiter=',') 
>>> out_f.getvalue() 
'9.984590199999999749e-01,-7.078051199999999543e-01,2.698137500000000188e-01,-6.077122000000000357e-01,9.639694999999999514e-02\n6.185671099999999756e-01,-7.468491299999999722e-01,2.009999199999999986e-01,9.972517100000000134e-01,-4.182675399999999932e-01\n7.996439699999999817e-01,5.662081199999999814e-01,-6.405534600000000189e-01,-5.057279300000000477e-01,-5.010063500000000447e-01\n' 

E caricarlo indietro come:

>>> in_f = cStringIO.StringIO(out_f.getvalue()) 
>>> np.loadtxt(in_f, delimiter=',') 
array([[ 0.99845902, -0.70780512, 0.26981375, -0.6077122 , 0.09639695], 
     [ 0.61856711, -0.74684913, 0.20099992, 0.99725171, -0.41826754], 
     [ 0.79964397, 0.56620812, -0.64055346, -0.50572793, -0.50100635]]) 
1

Il mio suggerimento, se si voglio davvero conservare la formattazione XML iniziale che hai, è quello di utilizzare il modulo json per convertire tra ndarray e string.

Controllare i seguenti passaggi:

import json, numpy 

w1 = numpy.array([[ 0.99845902, -0.70780512, 0.26981375, -0.6077122, 0.09639695], 
        [ 0.61856711, -0.74684913, 0.20099992, 0.99725171, -0.41826754], 
        [ 0.79964397, 0.56620812, -0.64055346, -0.50572793, -0.50100635]]) 

print w1 
print 

##### 

w1string = json.dumps(w1.tolist()) 

## NOW YOU COULD PASS "w1string" TO/FROM XML 

##### 


print w1string 
print 

w1back = numpy.array(json.loads(w1string)) 

print w1back 
print 
0

È possibile utilizzare numpy.ndarray.tostring() per convertire l'array in stringhe (byte matrice in realtà). Numpy.ndarray.tostring()

Quindi questo può essere utilizzato in seguito per leggere l'array utilizzando numpy.fromstring().

In [138]: x = np.arange(12).reshape(3,4) 

In [139]: x.tostring() 
Out[139]: '\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t\x00\x00\x00\n\x00\x00\x00\x0b\x00\x00\x00' 

In [140]: np.fromstring(x.tostring(), dtype=x.dtype).reshape(x.shape) 
Out[140]: 
array([[ 0, 1, 2, 3], 
     [ 4, 5, 6, 7], 
     [ 8, 9, 10, 11]]) 
+0

Nota che .tostring() .. np.fromstring() perde la forma della matrice; si legge di nuovo come una singola riga, quindi l'uso di .reshape() nell'esempio. Devi comunicare la forma in un altro modo. – dpwe