Numpy: np.left_shift und np.right_shift schlagen bei skalaren np.uint64-Typen fehl (Trac # 1931)

Erstellt am 20. Okt. 2012  ·  7Kommentare  ·  Quelle: numpy/numpy

_Ursprüngliches Ticket http://projects.scipy.org/numpy/ticket/1931 am 10.08.2011 vom Trac-Benutzer tlatorre, zugewiesen an unknown._

>>> np.uint64(5) << 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'left_shift' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule 'safe'
>>> np.uint64(5) >> 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'right_shift' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule 'safe'
00 - Bug numpy.core

Hilfreichster Kommentar

Die einfachere Lösung besteht darin, eine vorzeichenlose Ganzzahl für die Schicht zu verwenden:

np.uint64(5) << np.uint64(1)

Wie oben erwähnt, liegt das Problem in der Art und Weise, wie d-Typen einheitlich gemacht werden. Es ist nicht so trivial, generisch zu reparieren (siehe auch # 5668), obwohl die Schichtoperatoren möglicherweise speziell behandelt werden können. (PR-Begrüßung ist jedoch, wie gesagt, nicht trivial, sondern erfordert ein faires Verständnis darüber, wie über die internen Schleifen in UFUCs entschieden wird ...).

Alle 7 Kommentare

_ @ charris schrieb am 2011-08-13_

Dies liegt daran, dass die Schichtnummer als vorzeichenbehafteter Typ konvertiert wird und es keinen vorzeichenbehafteten Ganzzahltyp gibt, der groß genug ist, um ein uint64 aufzunehmen. Die Shift-Operatoren müssen spezielle Gehäuse haben, sie können auch bei Intel ausfallen, da die Hardware die nicht benötigten Bits maskiert, dh für int32 werden nur die unteren 5 Bits betrachtet.

_trac user parejkoj schrieb am 2012-07-27_

Ich konnte dies mit dem folgenden Lambda umgehen:

lshift = lambda x,s: np.uint64(x)*np.uint64(2**s)

Das funktioniert, ist aber nicht ideal. Es wäre sehr nützlich, dies in Numpy zu beheben.

Es ist fünf Jahre später ... ist das nicht ein wichtiges Thema? Ganzzahlen ohne Vorzeichen sollten keine Mehrdeutigkeit in Bezug auf Verschiebungen aufweisen.

Die einfachere Lösung besteht darin, eine vorzeichenlose Ganzzahl für die Schicht zu verwenden:

np.uint64(5) << np.uint64(1)

Wie oben erwähnt, liegt das Problem in der Art und Weise, wie d-Typen einheitlich gemacht werden. Es ist nicht so trivial, generisch zu reparieren (siehe auch # 5668), obwohl die Schichtoperatoren möglicherweise speziell behandelt werden können. (PR-Begrüßung ist jedoch, wie gesagt, nicht trivial, sondern erfordert ein faires Verständnis darüber, wie über die internen Schleifen in UFUCs entschieden wird ...).

Die einfachere Lösung besteht darin, eine vorzeichenlose Ganzzahl für die Schicht zu verwenden:

np.uint64 (5) << np.uint64 (1)

... was funktioniert, wenn Sie wissen, dass Sie mit numpy Ganzzahlen arbeiten, aber wenn Sie generischen Code verwenden (insbesondere etwas, das bereits in einem anderen Modul geschrieben wurde und außerhalb Ihrer Kontrolle liegt) wie

def f(x):
    return x | (x >> 1)

Dann können Sie es nicht sowohl für reguläre Python-Ganzzahlen als auch für np.uint64-Typen verwenden.

Ich versuche nicht zu behaupten, dass dies trivial ist (Wayyyy über meinen Fähigkeiten), aber ich denke, dass es eine hohe Priorität haben sollte.

@ jason-s - Ich stimme zu, dass das Problem sehr ärgerlich ist ... Leider sind nicht viele von uns gut genug damit vertraut, wie die Ufuncs intern funktionieren ...

Vielleicht könnte man zumindest Spezialfall-Skalare für die Verschiebung der Methode verwenden, anstatt sich auf die allgemeine Ufunc-Maschinerie zu verlassen. @charris : war es das, was du dir vorgestellt hast (wenn du dich nach 6 Jahren daran erinnern kannst ;-).

Siehe auch # 8002.

Persönlich, wenn wir alles noch einmal machen könnten, würde ich es vorziehen, das gesamte Casting / den Zwang so zu wiederholen, dass sich das Numpy-Casting im Wesentlichen wie das C-Casting verhält und dem Geist des C-Castings für Fälle folgt, die in C nicht existieren. Das Numpy-Casting Regeln sind seltsam und manchmal verwirrend (z. B. die Konvertierung von uint64 + int64 in float64 ). Aber wir haben dies viel auf der Liste diskutiert, es scheint schwer zu ändern.

Wenn ich auf solche Situationen stoße (siehe meinen Kommentar dort), verpacke ich einfach jeden einzelnen Wert in np.uint64 .

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen