Cómo modificar un NumPy.recarray usando sus dos vistas
-
20-08-2019 - |
Pregunta
Soy nuevo en Python y Numpy, y me enfrento a un problema, que no puedo modificar un numpy.recarray, cuando se aplica a vistas enmascaradas. Leo recarray de un archivo, luego creo dos vistas enmascaradas, luego trato de modificar los valores en for loop. Aquí hay un código de ejemplo.
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
Pero cuando imprimo el resultado
newFile = args[0] + ".no-zero-scale"
mlab.rec2csv(dat[m_Obsr][m_ZeroScale], newFile, delimiter=' ')
Todos los scale_means en los archivos siguen siendo cero.
Debo estar haciendo algo mal. ¿Existe una manera adecuada de modificar los valores de ¿ver? ¿Es porque estoy aplicando dos vistas una por una?
Gracias.
Solución
Creo que tiene un concepto erróneo en este término " vistas enmascaradas " y debería (re) leer El Libro (ahora se puede descargar gratis) para aclarar su comprensión.
Cito de la sección 3.4.2:
La selección avanzada se activa cuando el objeto de selección, obj, es un objeto de secuencia sin tupla, un ndarray (de tipo de datos entero o bool), o un tupla con al menos una secuencia objeto o ndarray (de tipo de datos entero o bool). Hay dos tipos de indexación avanzada: entero y Booleano Selección avanzada siempre devuelve una copia de los datos (contraste con corte básico que devuelve un ver).
Lo que está haciendo aquí es una selección avanzada (del tipo booleano) para que obtenga una copia y nunca la encuaderne en ningún lado: realice los cambios en la copia y luego simplemente deje que desaparezca, luego escriba un nueva copia nueva del original.
Una vez que comprenda el problema, la solución debe ser simple: haga su copia una vez, realice los cambios en esa copia y escriba esa misma copia. Es decir:
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=' ')