python - Numpy ¿modifica la matriz en su lugar?
arrays in-place (4)
Este es un truco que es un poco más general que las otras respuestas útiles aquí:
def normalize(array, imin = -1, imax = 1):
"""I = Imin + (Imax-Imin)*(D-Dmin)/(Dmax-Dmin)"""
dmin = array.min()
dmax = array.max()
array[...] = imin + (imax - imin)*(array - dmin)/(dmax - dmin)
Aquí estamos asignando valores a la array[...]
vistas en lugar de asignar estos valores a una nueva variable local dentro del alcance de la función.
x = np.arange(5, dtype=''float'')
print x
normalize(x)
print x
>>> [0. 1. 2. 3. 4.]
>>> [-1. -0.5 0. 0.5 1. ]
Tengo el siguiente código que intenta normalizar los valores de una matriz mxn
(se usará como entrada a una red neuronal, donde m
es el número de ejemplos de capacitación n
es la cantidad de características).
Sin embargo, cuando inspecciono la matriz en el intérprete después de ejecutar la secuencia de comandos, veo que los valores no están normalizados; es decir, todavía tienen los valores originales. Supongo que esto se debe a que la asignación a la variable de array
dentro de la función solo se ve dentro de la función.
¿Cómo puedo hacer esta normalización en su lugar? ¿O debo devolver una nueva matriz de la función normalizar?
import numpy
def normalize(array, imin = -1, imax = 1):
"""I = Imin + (Imax-Imin)*(D-Dmin)/(Dmax-Dmin)"""
dmin = array.min()
dmax = array.max()
array = imin + (imax - imin)*(array - dmin)/(dmax - dmin)
print array[0]
def main():
array = numpy.loadtxt(''test.csv'', delimiter='','', skiprows=1)
for column in array.T:
normalize(column)
return array
if __name__ == "__main__":
a = main()
Hay una buena forma de hacer la normalización en el lugar cuando se usa numpy. np.vectorize
es muy útil cuando se combina con una función lambda
cuando se aplica a una matriz. Vea el ejemplo a continuación:
import numpy as np
def normalizeMe(value,vmin,vmax):
vnorm = float(value-vmin)/float(vmax-vmin)
return vnorm
imin = 0
imax = 10
feature = np.random.randint(10, size=10)
# Vectorize your function (only need to do it once)
temp = np.vectorize(lambda val: normalizeMe(val,imin,imax))
normfeature = temp(np.asarray(feature))
print feature
print normfeature
Uno puede comparar el rendimiento con una expresión de generador, sin embargo, hay muchas otras maneras de hacerlo.
%%timeit
temp = np.vectorize(lambda val: normalizeMe(val,imin,imax))
normfeature1 = temp(np.asarray(feature))
10000 loops, best of 3: 25.1 µs per loop
%%timeit
normfeature2 = [i for i in (normalizeMe(val,imin,imax) for val in feature)]
100000 loops, best of 3: 9.69 µs per loop
%%timeit
normalize(np.asarray(feature))
100000 loops, best of 3: 12.7 µs per loop
Así que vectorizar definitivamente no es el más rápido, pero puede ser conveniente en casos donde el rendimiento no es tan importante.
Si desea aplicar operaciones matemáticas a una matriz numpy in situ, puede simplemente usar los operadores in situ estándar +=
, -=
, /=
, etc. Por ejemplo:
>>> def foo(a):
... a += 10
...
>>> a = numpy.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> foo(a)
>>> a
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
La versión in situ de estas operaciones es un poco más rápida para arrancar, especialmente para arreglos más grandes:
>>> def normalize_inplace(array, imin=-1, imax=1):
... dmin = array.min()
... dmax = array.max()
... array -= dmin
... array *= imax - imin
... array /= dmax - dmin
... array += imin
...
>>> def normalize_copy(array, imin=-1, imax=1):
... dmin = array.min()
... dmax = array.max()
... return imin + (imax - imin) * (array - dmin) / (dmax - dmin)
...
>>> a = numpy.arange(10000, dtype=''f'')
>>> %timeit normalize_inplace(a)
10000 loops, best of 3: 144 us per loop
>>> %timeit normalize_copy(a)
10000 loops, best of 3: 146 us per loop
>>> a = numpy.arange(1000000, dtype=''f'')
>>> %timeit normalize_inplace(a)
100 loops, best of 3: 12.8 ms per loop
>>> %timeit normalize_copy(a)
100 loops, best of 3: 16.4 ms per loop
def normalize(array, imin = -1, imax = 1):
"""I = Imin + (Imax-Imin)*(D-Dmin)/(Dmax-Dmin)"""
dmin = array.min()
dmax = array.max()
array -= dmin;
array *= (imax - imin)
array /= (dmax-dmin)
array += imin
print array[0]