Come modificare un NumPy.recarray usando le sue due viste
-
20-08-2019 - |
Domanda
Sono nuovo di Python e Numpy e sto affrontando un problema che non riesco a modificare un numpy.recarray quando si applicano alle viste mascherate. Ho letto ricomporre da un file, quindi ho creato due viste mascherate, quindi ho provato a modificare i valori in for loop. Ecco un esempio di codice.
import numpy as np
import matplotlib.mlab as mlab
dat = mlab.csv2rec(args[0], delimiter=' ')
m_Obsr = dat.is_observed == 1
m_ZeroScale = dat[m_Obsr].scale_mean < 0.01
for d in dat[m_Obsr][m_ZeroScale]:
d.scale_mean = 1.0
Ma quando stampo il risultato
newFile = args[0] + ".no-zero-scale"
mlab.rec2csv(dat[m_Obsr][m_ZeroScale], newFile, delimiter=' ')
Tutti i scale_means nei file sono ancora zero.
Devo fare qualcosa di sbagliato. Esiste un modo corretto di modificare i valori di vista? È perché sto applicando due viste una per una?
Grazie.
Soluzione
Penso che tu abbia un'idea sbagliata in questo termine " viste mascherate " e dovrebbe (ri) leggere The Book (ora scaricabile gratuitamente) per chiarire la tua comprensione.
Cito dalla sezione 3.4.2:
La selezione avanzata viene attivata quando l'oggetto di selezione, obj, è a oggetto sequenza non tupla, un ndarray (di tipo di dati intero o bool) o a tupla con almeno una sequenza object o ndarray (di tipo dati intero o bool). Ce ne sono di due tipi di indicizzazione avanzata: intero e Booleano. Selezione avanzata sempre restituisce una copia dei dati (contrasto con lo slicing di base che restituisce a view).
Quello che stai facendo qui è una selezione avanzata (di tipo booleano) in modo da ottenere una copia e non vincolarla mai da nessuna parte: fai le tue modifiche sulla copia e poi lasciala andare via, quindi scrivi un nuova copia originale dall'originale.
Una volta compreso il problema, la soluzione dovrebbe essere semplice: esegui una copia una volta, apporta le modifiche su quella copia e scrivi quella stessa copia. Cioè:.
dat = mlab.csv2rec(args[0], delimiter=' ')
m_Obsr = dat.is_observed == 1
m_ZeroScale = dat[m_Obsr].scale_mean < 0.01
the_copy = dat[m_Obsr][m_ZeroScale]
for d in the_copy:
d.scale_mean = 1.0
newFile = args[0] + ".no-zero-scale"
mlab.rec2csv(the_copy, newFile, delimiter=' ')