Seite 1 von 1
Matrixen
Verfasst: Dienstag 26. März 2019, 20:16
von Hypec
Hallo,
mein Ziel ist es mit diesem Code 2 Matrixen zu generieren und dann zu addieren. Das Problem ist in Schritt 3 bekommt auf einmal die Matrixe m die gleichen Werte wie m2 obwohl ja eigentlich nur zu jeder Zahl eine 1 addiert werden soll. Weiß jemand was ich hier Falsch mache?
Code: Alles auswählen
import matrix
def main():
Matrix = matrix.matrix()
m = Matrix.Matrix(3,2)
m2 = Matrix.Matrix(3,2)
print(m)
print(m2)
print('schritt 1')
#m = Matrix.randomize()
m2 = Matrix.randomize()
print(m)
print(m2)
print('schritt 2')
m = Matrix.add(1)
print(m)
print(m2)
print('schritt 3')
m2 = Matrix.add(m)
print(m2)
main()
Code: Alles auswählen
import random
import numpy as np
class matrix:
def Matrix(self, rows=2, cols=2):
self.rows = rows
self.cols = cols
self.matrix = np.zeros(shape=(rows,cols))
return self.matrix
def randomize(self):
for i in range(self.rows):
for j in range(self.cols):
self.matrix[i][j] = random.randint(0, 10)
return self.matrix
def add(self, n):
m = np.zeros(shape=(1,1))
if type(n) == type(m):
for i in range(self.rows):
for j in range(self.cols):
self.matrix[i][j] += n[i][j]
else:
for i in range(self.rows):
for j in range(self.cols):
self.matrix[i][j] += n
return self.matrix
def scale(self, n):
for i in range(self.rows):
for j in range(self.cols):
self.matrix[i][j] *= n
return self.matrix
Re: Matrixen
Verfasst: Dienstag 26. März 2019, 20:45
von __deets__
Vor allem machst du einen Fehler indem du numpy nicht benutzt. Von grundlegenden Verständnisproblemen bei der Nutzung von Klassen angesehen, kannst du dir die ganzen mühselig programmierten und langsamen Operationen sparen, und einfach direkt zwei numpy Objekte addieren. Oder skalieren.
Re: Matrixen
Verfasst: Dienstag 26. März 2019, 21:25
von ThomasL
@deets ich gehe davon aus, dass Hypec die Tutorials von The Coding Train, die in Java/Javascript sind, genauso wie ich vor 1 Jahr, in Python
nach programmiert. Sehr empfehlenswert. So bekommt man ein grundlegendes Verständnis wie Neuronale Netze / Perceptrons funktionieren.
Ohne das jetzt ausprobiert zu haben, ist die Initialisierung der Klasse hier ein Problem.
Code: Alles auswählen
class matrix:
def Matrix(self, rows=2, cols=2):
self.rows = rows
self.cols = cols
self.matrix = np.zeros(shape=(rows, cols))
return self.matrix
sollte lauten
Code: Alles auswählen
class matrix:
def __init__(self, rows=2, cols=2):
self.rows = rows
self.cols = cols
self.matrix = np.zeros(shape=(rows, cols))
@Hypec
schau mal hier rein
https://realpython.com/courses/intro-ob ... op-python/
Re: Matrixen
Verfasst: Dienstag 26. März 2019, 21:29
von __deets__
@ThomasL: das habe ich mir schon gedacht. Aber dabei muss man ja nun nicht Dinge ums verrecken schlechter machen, als sie einfach so schon gehen. Eine Matrix zu addieren kann numpy halt schon. Und das Verständnis von NN wird davon ja nicht besser.
Re: Matrixen
Verfasst: Mittwoch 27. März 2019, 15:17
von Hypec
Ja ich bearbeite die Tutorials von The Coding Train. Das ganze aufwändige addieren hab ich angefangen weil ich versucht habe mit so wening Libarys wie möglich zu arbeiten. Da es funktioniert habe ich es so gelassen als ich angefangen habe numpy zu nützen.
Das mit def __init__ habe ich auch schon Probiert allerdings bekomme ich dann keine Matrix mehr zurück.
Sondern so etwas:
Code: Alles auswählen
<matrix.matrix object at 0x000001BFA591E588>
<matrix.matrix object at 0x000001BFA591EA58>
Re: Matrixen
Verfasst: Mittwoch 27. März 2019, 15:26
von __deets__
Das ist deine matrix. Wenn du deine Klasse (entgegen der Konvention) matrix klein schrieben nennst, und die in einem Modul matrix steckt, dann heisst einen Instanz davon <matrix.matrix object at adresse>
Re: Matrixen
Verfasst: Mittwoch 27. März 2019, 16:48
von Hypec
Das mit der Konvention wusste ich nicht. Aber das ändert auch nichts daran das ich keine Matrix mehr zurückbekomme sondern eine Instanz mit der ich so recht Wenig anfangen kann.
Re: Matrixen
Verfasst: Mittwoch 27. März 2019, 16:54
von __blackjack__
@Hypec: Doch Du bekommst eine Matrix zurück. Wenn die `repr()`-Darstellung davon anders aussehen soll, zum Beispiel den Inhalt der Matrix enthalten soll, dann musst Du das halt entsprechend programmieren, also eine `__repr__()`-Methode implementieren. Oder das `attr`-Modul verwenden und das die `__repr__()` für Dich schreiben lassen.
Oder Du benutzt die Numpy-Objekte. Die haben nicht nur die Rechenoperationen schon implementiert, sondern auch eine `__repr__()`. Durch das nicht-nutzen von Numpy machst Du Dir nur unnötig Arbeit.
Edit: Dein Beispiel im ersten Beitrag ohne unnötige zusätzliche eigene Matrix-Klasse:
Code: Alles auswählen
#!/usr/bin/env python3
import numpy as np
def main():
m = np.zeros((3, 2), int)
m2 = np.zeros((3, 2), int)
print(m)
print(m2)
print('schritt 1')
m2 = np.random.randint(10, size=(m2.shape))
print(m)
print(m2)
print('schritt 2')
m += 1
print(m)
print(m2)
print('schritt 3')
m2 += m
print(m2)
if __name__ == '__main__':
main()
Ausgabe:
Code: Alles auswählen
[[0 0]
[0 0]
[0 0]]
[[0 0]
[0 0]
[0 0]]
schritt 1
[[0 0]
[0 0]
[0 0]]
[[7 6]
[3 7]
[3 5]]
schritt 2
[[1 1]
[1 1]
[1 1]]
[[7 6]
[3 7]
[3 5]]
schritt 3
[[8 7]
[4 8]
[4 6]]
Re: Matrixen
Verfasst: Donnerstag 28. März 2019, 16:51
von Hypec
Das ganze war nur um den Code zu testen das ich das nicht immer Eingeben muss also ich will eigentlich schon mit der Klasse weiter arbeiten.
Aber danke für deine Hilfe dann schreib ich die Klasse jetzt mit repr() und numpy.
Re: Matrixen
Verfasst: Donnerstag 28. März 2019, 17:06
von __blackjack__
@Hypec: Warum willst Du mit Klassen arbeiten? Also ich meine jetzt im speziellen mit einer Klasse die effektiv das gleiche macht/kann wie die Klasse `array` aus Numpy? Ich könnte das verstehen wenn man es ohne Numpy machen möchte, um mal zu sehen wie man eine Matrix als Datentyp selber implementiert, aber wenn die Matrix-Implementierung sich selbst auf eine bereits vorhandene abstützt, lernt man doch auch nicht wirklich etwas‽
Re: Matrixen
Verfasst: Donnerstag 28. März 2019, 17:17
von Hypec
Ich will das ganze so machen das ich es einfach nutzen kann und später dann eigentlich über Inputs regeln kann, was jetzt mit den Matrixen gemacht wird. Außerdem wollte ich numpy ursprünglich nur wegen des Datentypes nutzen das ich schauen kann was ich addieren will.
Re: Matrixen
Verfasst: Donnerstag 28. März 2019, 17:35
von __blackjack__
@Hypec: Bei Deine Klasse ist neben der fehlenden `__init__()` auch falsch, das Du überall die interne Matrix als Rückgabewert hast, was die ”Methoden” zu einer komischen Mischung aus Methode und Funktion macht die Numpy-Arrays zurück geben, also letztendlich arbeitest Du dann sowieso schon mit Numpy-Arrays.
Was man ja auch am Argument von `add()` sieht: Du testest nicht ob das ein Exemplar *Deiner* Klasse ist, sondern ob das ein Numpy-Array ist. Wobei man, wenn man schon auf Typen testen muss, nicht `type()` und ``==`` verwendet, sondern `isinstance()`. Man muss auch kein Array mit einer Zeile/Spalte erstellen nur um den Typ zu bekommen – der ist ja bekannt: `numpy.ndarray`.
Dass das Attribut eines `Matrix`-Objekts selbst wieder `matrix` heisst, ist auch wieder so eine Art Alarmzeichen, denn eine Matrix enthält keine Matrix sondern Werte.
Die `__init__()` über die Anzahl der Zeilen und Spalten zu regeln erschwert es eine typische `__repr__()`-Darstellung zu implementieren, weil man damit ja nur Matrizen erstellen kann, die überall 0 als Wert haben. Man würde also eher die Zeilen- und Spalten-Variante in eine Klassenmethode verlagern.
`rows` und `cols` als Attribute sind redundant, weil diese Information ja schon in `shape` vom Numpy-Array steckt.
Die Klasse aus dem Ausgangsbeispiel würde in Python das also eher so aussehen (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
import numpy as np
class Matrix:
def __init__(self, values):
self.values = values
def __repr__(self):
return f'{self.__class__.__name__}({self.values!r})'
@property
def rows(self):
return self.values.shape[0]
@property
def cols(self):
return self.values.shape[1]
def randomize(self):
self.values = np.random.randint(0, 10, self.values.shape)
def add(self, other):
if isinstance(other, Matrix):
other = other.values
self.values = self.values + other
def scale(self, factor):
self.values = self.values * factor
@classmethod
def from_shape(cls, rows, cols):
return cls(np.zeros((rows, cols), int))