webentwicklung-frage-antwort-db.com.de

Numpy Array an Ort und Stelle ändern?

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()
24
User

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
22
senderle

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. ]
4
Ian Hincks
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]
4
ely

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.

1
salomonvh