33 Stimmen

numpy divide entlang der Achse

Gibt es eine Numpy-Funktion, um ein Array entlang einer Achse mit Elementen aus einem anderen Array zu unterteilen? Nehmen wir zum Beispiel an, ich habe ein Array a mit der Form (l,m,n) und einem Array b mit Form (m,); ich suche etwas, das dem entspricht:

def divide_along_axis(a,b,axis=None):
    if axis is None:
        return a/b
    c = a.copy()
    for i, x in enumerate(c.swapaxes(0,axis)):
        x /= b[i]
    return c

Dies ist zum Beispiel bei der Normalisierung einer Reihe von Vektoren nützlich:

>>> a = np.random.randn(4,3)
array([[ 1.03116167, -0.60862215, -0.29191449],
       [-1.27040355,  1.9943905 ,  1.13515384],
       [-0.47916874,  0.05495749, -0.58450632],
       [ 2.08792161, -1.35591814, -0.9900364 ]])
>>> np.apply_along_axis(np.linalg.norm,1,a)
array([ 1.23244853,  2.62299312,  0.75780647,  2.67919815])
>>> c = divide_along_axis(a,np.apply_along_axis(np.linalg.norm,1,a),0)
>>> np.apply_along_axis(np.linalg.norm,1,c)
array([ 1.,  1.,  1.,  1.])

43voto

FredL Punkte 921

Für das spezifische Beispiel, das Sie gegeben haben: ein (l,m,n) Array durch (m,) zu teilen, können Sie np.newaxis verwenden:

a = np.arange(1,61, dtype=float).reshape((3,4,5)) # Create a 3d array 
a.shape                                           # (3,4,5)

b = np.array([1.0, 2.0, 3.0, 4.0])                # Create a 1-d array
b.shape                                           # (4,)

a / b                                             # Gives a ValueError

a / b[:, np.newaxis]                              # The result you want 

Sie können alles über die Übertragungsregeln lesen aquí . Sie können newaxis bei Bedarf auch mehrmals verwenden. (z. B. um eine Form (3,4,5,6)-Anordnung durch eine Form (3,5)-Anordnung zu teilen).

Meinem Verständnis der Dokumente nach vermeidet die Verwendung von newaxis + broadcasting auch das unnötige Kopieren von Arrays.

Indizierung, neue Achsen usw. werden ausführlicher beschrieben aquí jetzt. (Die Dokumentation wurde seit der ersten Veröffentlichung dieser Antwort umstrukturiert).

2voto

Owen Punkte 37648

Ich denke, man kann dieses Verhalten mit dem üblichen Broadcasting-Verhalten von Numpy erreichen:

In [9]: a = np.array([[1., 2.], [3., 4.]])

In [10]: a / np.sum(a, axis=0)
Out[10]:
array([[ 0.25      ,  0.33333333],
       [ 0.75      ,  0.66666667]])

Wenn ich das richtig verstanden habe.

Wenn Sie die andere Achse wollen, können Sie alles umdrehen:

> a = np.random.randn(4,3).transpose()
> norms = np.apply_along_axis(np.linalg.norm,0,a)
> c = a / norms
> np.apply_along_axis(np.linalg.norm,0,c)
array([ 1.,  1.,  1.,  1.])

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X