Ich definiere eine rationale Zahlenklasse wie folgt:
class ratio():
def __init__(q,n:int,d:int=1):
q.n=n
q.d=d
Und ich überlade alle binären Operatoren, um sie für rationale Zahlen zu definieren. Ich möchte diese auch erweitern, um mit Arrays zu arbeiten, wie es numpy bereits mit Skalaren tut.
Ich habe bereits genug Code für
In: a,b=ratio(2,3),ratio(6,8)
In: print(c:=a*b)
Out: 3/4
Wobei c auch ein Verhältnis ist. Ich möchte das können:
In: c*np.array([a,b])
Wobei die Ausgabe äquivalent ist
In: np.array([c*a,c*b])
Ich denke, der beste Weg, dies zu tun, besteht darin, einen neuen numpy dtype zu definieren, der mit meinen Ratio-Klassenmethoden funktioniert, aber das Lesen der dtype-Dokumentation erweist sich als zu verwirrend für mich. Irgendwelche Tipps? Gehe ich das überhaupt richtig an? Außerdem, für die Neugierigen, hier sind alle Klassenmethoden, die ich bisher habe
class ratio():
def __init__(q,n:int,d:int=1):
q.n=n
q.d=d
q.simplify()
def __str__(q):
return '{}/{}'.format(q.n,q.d)
def value(q):
return q.n/q.d
def simplify(q):
g=np.gcd(q.n,q.d)
q.n//=g
q.d//=g
def __mul__(q, r):
if isinstance(r,ratio): return ratio(q.n*r.n,q.d*r.d)
elif isinstance(r,int): return ratio(q.n*r,q.d)
else: return q.value()*r
def __rmul__(q,r):
return q.__mul__(r)
def __truediv__(q, r):
if isinstance(r,ratio): return ratio(q.n*r.d,q.d*r.n)
elif isinstance(r,int): return ratio(q.n,q.d*r)
else: return q.value()/r
def __rtruediv__(q,r):
if isinstance(r,int): return ratio(r*q.d,q.n)
else: return q.value()/r
Lösung des Problems
Wie von @juanpa.arrivillaga gesagt, gibt es bereits eine Bruchklasse in der Standardbibliothek.
Sie können es wie folgt aufrufen:
from fractions import Fraction
f = Fraction(numerator=17, denominator=281)
und es hat eine aufgerufene Methode, as_integer_ratio
die im Grunde mit Ihrer Vereinfachung identisch ist.
Bearbeiten: Tests für Ihre Anwendungsfälle hinzugefügt:
>>> from fractions import Fraction
>>> import numpy as np
>>> a = Fraction(2,3)
>>> b=Fraction(6,8)
>>> a*b
Fraction(1, 2)
>>> c= a*b
>>> c*np.array([a,b])
array([Fraction(1, 3), Fraction(3, 8)], dtype=object)
Seien Sie vorsichtig, in Ihrem Beispiel c=a*b
war es 3/4 wert, was falsch ist.
Keine Kommentare:
Kommentar veröffentlichen