2015-06-12 13 views
9

Quindi ho un DB con un paio di anni di dati del sito. Ora sto tentando di utilizzare questi dati per l'analisi - la pianificazione e lo smistamento dei costi pubblicitari tramite parole chiave, ecc.Salvataggio del dizionario di array numpy

Uno dei dati necessari dal DB richiede alcuni minuti per essere completato. Mentre potrei passare un po 'di tempo ad ottimizzare le istruzioni SQL che uso per ottenere i dati preferisco semplicemente lasciare quella classe ed è solo SQL, prendere i dati e salvare i risultati in un file di dati per un recupero più veloce in seguito. La maggior parte di questi dati DB non cambierà quindi potrei scrivere uno script python separato per aggiornare il file ogni 24 ore e quindi usare quel file per questa attività a lungo termine.

I dati vengono restituiti come un dizionario di array numpy. Quando uso numpy.save('data', data) il file viene salvato bene. Quando uso data2 = numpy.load('data.npy') carica il file senza errori. Tuttavia, l'uscita data2 non corrisponde all'originale data.

In particolare, la riga data == data2 restituisce false. Inoltre, se io uso il seguente:

for key, key_data in data.items(): 
    print key 

funziona. Ma quando sostituisco data.items() con data2.items() poi ho un errore:

AttributeError: 'numpy.ndarray' object has no attribute 'items' 

Utilizzando type(data) ottengo dict. Utilizzando type(data2) ottengo numpy.ndarray.

Quindi come posso risolvere questo? Voglio che i dati caricati siano uguali ai dati che ho passato per il salvataggio. C'è un argomento per numpy.save per risolvere questo o ho bisogno di qualche forma di semplice funzione di riformattazione per riformattare i dati caricati nella struttura corretta?

I tentativi di entrare nel ciclo ndarray tramite loop o indicizzazione portano a errori sull'indicizzazione di un array 0-d. Anche la trasmissione in questo modo dict(data2) non riesce per l'iterazione su un array 0-d. Tuttavia, Spyder mostra il valore dell'array e include i dati che ho salvato. Non riesco a capire come arrivarci.

Se ho bisogno di riformattare i dati caricati, mi piacerebbe qualche esempio di codice su come farlo. sguardo

risposta

11

Let ad un piccolo esempio:

In [819]: N 
Out[819]: 
array([[ 0., 1., 2., 3.], 
     [ 4., 5., 6., 7.], 
     [ 8., 9., 10., 11.]]) 

In [820]: data={'N':N} 

In [821]: np.save('temp.npy',data) 

In [822]: data2=np.load('temp.npy') 

In [823]: data2 
Out[823]: 
array({'N': array([[ 0., 1., 2., 3.], 
     [ 4., 5., 6., 7.], 
     [ 8., 9., 10., 11.]])}, dtype=object) 

np.save è stato progettato per salvare le matrici numpy. data è un dizionario. Quindi lo ha avvolto in un array di oggetti e ha utilizzato pickle per salvare quell'oggetto. Il tuo data2 probabilmente ha lo stesso carattere.

Si arriva al array con:

In [826]: data2[()]['N'] 
Out[826]: 
array([[ 0., 1., 2., 3.], 
     [ 4., 5., 6., 7.], 
     [ 8., 9., 10., 11.]]) 
+2

Non mi sarebbe mai venuto in mente di usare '[()]'. Non penso di aver mai visto un indice simile in nessun'altra lingua che ho usato. –

+0

Se si salva solo un dizionario di array, e numpy.save usa sempre pickle, si potrebbe anche usare pickle direttamente? – TNT

+0

'np.save' è il modo più diretto e compatto per salvare un array. Per un dizionario di array, preferirei 'np.savez'. Per un dizionario, che potrebbe avere roba diversa dagli array, 'np.save' come usato qui, o' pickle' sono probabilmente equivalenti. La cosa divertente è che ho problemi a eseguire 'pickle' (senza leggere i documenti) per fare un confronto. – hpaulj

4

Mi è piaciuto molto il deepdish (li salva in formato HDF5):

>>> import deepdish as dd 
>>> d = {'foo': np.arange(10), 'bar': np.ones((5, 4, 3))} 
>>> dd.io.save('test.h5', d) 

$ ddls test.h5 
/bar      array (5, 4, 3) [float64] 
/foo      array (10,) [int64] 

>>> d = dd.io.load('test.h5') 

per la mia esperienza, sembra essere parzialmente spezzato per grandi serie di dati, però: (

+0

In che modo è rotto per set di dati di grandi dimensioni? –

+1

Ho riscontrato alcuni problemi con il salvataggio di elenchi di oggetti estremamente grandi –

1

Quando si salva un dizionario con numpy, il dizionario è codificato in una matrice. Per avere quello che ti serve, si può fare come in questo esempio:

my_dict = {'a' : np.array(range(3)), 'b': np.array(range(4))} 

np.save('my_dict.npy', my_dict)  

my_dict_back = np.load('my_dict.npy') 

print(my_dict_back.item().keys())  
print(my_dict_back.item().get('a')) 

Così si sono probabilmente manca .item() per il dizionario Reloaded. Check this out:

for key, key_d in data2.item().items(): 
    print key, key_d 

Il confronto my_dict == my_dict_back.item() funziona solo per i dizionari che non dispone di elenchi o matrici nei loro valori.