2012-12-05 6 views
6

Ich versuche, numpy.complex64 Unterklasse zu bilden, um die Art und Weise numpy speichert die Daten, (zusammenhängende, Real-und Imaginärteil abwechselnd) verwenden aber meine eigenen __add__, __sub__, ... Routinen.Subclassing numpy Skalartypen

Mein Problem ist, dass, wenn ich ein numpy.ndarray machen, das Setzen von dtype=mysubclass, ich numpy.ndarray mit dtype='numpy.complex64' anstelle bekommen, die in numpy führt nicht meine eigenen Funktionen für Ergänzungen verwenden, Subtraktionen und so weiter.

Beispiel:

import numpy as np 
class mysubclass(np.complex64): 
    pass 

a = mysubclass(1+1j) 
A = np.empty(2, dtype=mysubclass) 

print type(a) 
print repr(A) 

Ausgang:

<class '__main__.mysubclass'> 
array([ -2.07782988e-20 +4.58546896e-41j, -2.07782988e-20 +4.58546896e-41j], dtype=complex64)' 

Wer weiß, wie dies zu tun?

Dank im Voraus - Soren

+0

Ich denke, a sah eine ähnliche Frage vor kurzem, aber kann es nicht sofort finden ... – NPE

Antwort

3

Das System NumPy Typ nur aus C erweitert werden soll, über die PyArray_RegisterDataType Funktion. Es kann möglich sein, auf diese Funktionalität von Python mit Ctypes zugreifen, aber ich würde es nicht empfehlen; besser, um eine Erweiterung in C oder Cython zu schreiben, oder Unterklasse ndarray als @seberg beschreibt.

Es gibt ein einfaches Beispiel dtype im NumPy-Quellbaum: newdtype_example/floatint.c. Wenn Sie in Pyrex sind, kann reference.pyx in der pytables Quelle einen Blick wert sein.

+0

Ich hatte gehofft, aus C zu bleiben, aber ich denke, es ist schwer zu vermeiden, wenn diese Art von Sachen. Ich werde das Beispiel betrachten und mein Glück versuchen - danke! – Soren

3

Beachten Sie, dass Skalare und Arrays relativ unterschiedlich sind. np.complex64 (dies ist 32-Bit-Float, nur zu beachten, nicht doppelte Genauigkeit). Sie können das Array nicht so ändern, Sie müssen stattdessen das Array ableiten und dann seine __add__ und __sub__ überschreiben.

Wenn das alles ist, was Sie tun möchten, sollte es einfach funktionieren, sehen Sie sich http://docs.scipy.org/doc/numpy/user/basics.subclassing.html an, da das Unterklassifizieren eines Arrays nicht so einfach ist.

Allerdings, wenn Sie diesen Typ auch als Skalar verwenden möchten. Wenn Sie zB Skalare auswerten wollen, wird es zumindest momentan schwieriger. Sie können ein wenig weiter gehen, indem Sie __array_wrap__ definieren, um für einige Reduce-Funktionen in Skalare in Ihren eigenen Skalartyp zu konvertieren. Für die Indizierung funktioniert es in allen Fällen so, als ob Sie Ihre eigene __getitem__ derzeit definieren könnten.

In allen Fällen verwenden Sie bei diesem Ansatz immer noch den komplexen Datentyp, und alle Funktionen, die nicht explizit überschrieben werden, verhalten sich immer noch gleich. @ecatmur erwähnt, dass Sie neue Datentypen von der C-Seite erstellen können, wenn das wirklich das ist, was Sie wollen.

+0

Es scheint, dass das Erstellen des dtype in C der bessere Ansatz ist. Vielen Dank! – Soren