2016-07-12 2 views
2

Ich versuche zu verstehen, wie sich die Übertragung von numpy auf die Ausgabe von np.allclose auswirkt.Warum ermöglicht die Übertragung von numpy manchmal den Vergleich von Arrays unterschiedlicher Länge?

>>> np.allclose([], [1.]) 
True 

Ich sehe nicht, warum das funktioniert, aber dies nicht:

>>> np.allclose([], [1., 2.]) 
ValueError: operands could not be broadcast together with shapes (0,) (2,) 

Was sind die Regeln hier? Ich kann in der numpy docs nichts über leere Arrays finden.

+0

'Zwei Dimensionen kompatibel sind, wenn sie gleich sind, oder einer von ihnen ist 1 '- Nun, das ist sicherlich richtig, also sollten die beiden per Definition kompatibel sein. Allerdings sehe ich nicht, wie dies intuitiv sinnvoll für eine Dimension 0 vs 1 ist. – cel

+0

@cel: siehe Antwort unten – Julien

+0

@cel betrachten 'np.allclose ([], 1)'. Ihre Dimension ist '(0,)' und '()', also weder gleich noch 1.Ist das die einzige Kompatibilitätsregel? –

Antwort

1

Rundfunk Regeln hinaus gelten auch,

In [7]: np.array([])+np.array([1.]) 
Out[7]: array([], dtype=float64) 

In [8]: np.array([])+np.array([1.,2.]) 
.... 

ValueError: operands could not be broadcast together with shapes (0,) (2,) 

einen Blick auf die Formen aussehen lassen.

In [9]: np.array([]).shape,np.array([1.]).shape,np.array([1,2]).shape 
Out[9]: ((0,), (1,), (2,)) 

(0,) und (1,) - die (1,) können die Form der anderen Anordnung entsprechen eingestellt werden. Eine 1 Dimension kann angepasst werden, um zu dem anderen Array zu passen, von Beispiel erhöht von 1 auf 3. Aber hier wurde es (scheinbar) von 1 auf 0 angepasst. Normalerweise arbeite ich nicht mit Arrays mit einer 0-Dimension, aber das sieht so aus eine richtige Verallgemeinerung höherer Dimensionen.

Versuchen Sie (0,) und (1,1). Das Ergebnis ist ein (1,0):

In [10]: np.array([])+np.array([[1.]]) 
Out[10]: array([], shape=(1, 0), dtype=float64) 

(0,), (1,1) => (1,0), (1,1) => (1,0)

Wie für den 2. Fall mit Formen (0,) und (2,); Es ist keine Dimension der Größe 1 einzustellen, daher der Fehler.

Shapes (0,) und (2,1) Sie übertragen (zu (2,0)):

In [12]: np.array([])+np.array([[1.,2]]).T 
Out[12]: array([], shape=(2, 0), dtype=float64) 
1

Broadcasting wirkt sich nicht auf andere Weise auf np.allclose aus als auf andere Funktionen.

Wie im Kommentar von @cel, hat [1.] die Dimension 1 und kann daher auf jede andere Dimension, einschließlich 0, übertragen werden. Andererseits ist [1., 2.] von Dimension 2 und kann daher nicht gesendet werden.

Jetzt warum allclose([],[1.]) == True? Dies macht eigentlich Sinn: Es bedeutet, dass alle Elemente in [] nahe 1. sind. Das Gegenteil würde bedeuten, dass es in [] mindestens ein Element gibt, das nicht nahe bei 1. liegt, was offensichtlich False ist, da es überhaupt keine Elemente in [] gibt.

Eine weitere Möglichkeit, darüber nachzudenken ist, sich zu fragen, wie Sie tatsächlich Code allclose() würde:

def allclose(array, target=1.): 
    for x in array: 
     if not isclose(x, target): 
      return False 
    return True 

Diese True zurückkehren würde, wenn sie mit [] genannt.

+1

Ich stimme im Prinzip zu, aber wie würden Sie 'np.allclose ([1.], [])' Das ist auch 'interpretieren Wahr? Alle Elemente in [1.] sind gleich ... hum ... nichts? Der andere Weg fühlt sich sehr unintuitiv an. – cel

+0

@cel: weil du es nicht so lesen solltest: '[1.]' wird zu '[]' übertragen, nicht umgekehrt. (So ​​wie es "[1.]" ist, das zu "[1., 2., 3.]" übertragen würde und nicht umgekehrt wäre das auch Unsinn.) – Julien

Verwandte Themen