Ich habe den folgenden Code, der versucht, die Werte eines m x n
-Arrays zu normalisieren (Er wird als Eingabe für ein neuronales Netzwerk verwendet, wobei m
die Anzahl der Trainingsbeispiele und n
die Anzahl der Features ist).
Wenn ich jedoch das Array im Interpreter nach der Ausführung des Skripts überprüfe, sehe ich, dass die Werte nicht normalisiert sind. Das heißt, sie haben immer noch die ursprünglichen Werte. Ich vermute, das liegt daran, dass die Zuweisung zu der Variablen array
innerhalb der Funktion nur innerhalb der Funktion angezeigt wird.
Wie kann ich diese Normalisierung durchführen? Oder muss ich ein neues Array von der Normalisierungsfunktion zurückgeben?
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 __== "__main__":
a = main()
Wenn Sie mathematische Operationen direkt auf ein numpy-Array anwenden möchten, können Sie einfach die standardmäßigen In-Place-Operatoren +=
, -=
, /=
usw. verwenden. So zum Beispiel:
>>> 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])
Die In-Place-Version dieser Vorgänge ist ein wenig schneller zu starten, insbesondere für größere Arrays:
>>> 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
Dies ist ein Trick, der etwas allgemeiner ist als die anderen nützlichen Antworten hier:
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)
Hier weisen wir der Ansicht array[...]
Werte zu, anstatt diese Werte einer neuen lokalen Variablen im Funktionsumfang zuzuweisen.
x = np.arange(5, dtype='float')
print x
normalize(x)
print x
>>> [0. 1. 2. 3. 4.]
>>> [-1. -0.5 0. 0.5 1. ]
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]
Es gibt eine gute Möglichkeit, die In-Place-Normalisierung bei Verwendung von NumPy durchzuführen. np.vectorize
ist sehr nützlich, wenn es mit einer lambda
-Funktion kombiniert wird, wenn es auf ein Array angewendet wird. Siehe das Beispiel unten:
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
Man kann die Leistung mit einem Generatorausdruck vergleichen, es gibt jedoch viele andere Möglichkeiten, dies zu tun.
%%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
Vektorisieren ist also definitiv nicht das Schnellste, kann aber in Fällen überzeugen, in denen Leistung nicht so wichtig ist.