Zweidimensionale innere Liste durchlaufen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
NWA
User
Beiträge: 48
Registriert: Mittwoch 3. Februar 2021, 11:40

Hi,

ich möchte gerne eine Liste effizient meinem Diagramm übergeben; habe aber Verständnisprobleme mit zweidimensionalen Listen. Eigentlich geht es darum matplotlib.pyplot.step(Liste x, Liste y) aus einer vorhandene zweidimensionalen Liste immer das x.Element zum Zeichnen zu übergeben- ohne eine neue Liste erstellen zu müssen. Getestet habe ich es damit:

Code: Alles auswählen

a = [[1,2],[3,4],[5,6],[7,8]]
print(a[0:2][1])

>> [3, 4]
print() gibt aber nur das zweite Element zurück. Numpy soll das wohl können, aber leider kann in einem array nur ein Datentyp verwendet werden. Bei mir sind aber int und float gemischt.
Sirius3
User
Beiträge: 18317
Registriert: Sonntag 21. Oktober 2012, 17:20

NWA
User
Beiträge: 48
Registriert: Mittwoch 3. Februar 2021, 11:40

@Sirius3

Wo ist denn hier der Dankeknopf....
NWA
User
Beiträge: 48
Registriert: Mittwoch 3. Februar 2021, 11:40

Ich glaube numpy ist ungeeignet, weil arrays unveränderlich sind. Er würde bei jeder Änderung des Feldes ein neues Feld erstellen. Was ich ja gerade vermeiden möchte...
Benutzeravatar
snafu
User
Beiträge: 6894
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@NWA: So bekommt man jedes zweite Element der inneren Listen:

Code: Alles auswählen

>>> data = np.array([[1,2],[3,4],[5,6],[7,8]])
>>> data
array([[1, 2],
       [3, 4],
       [5, 6],
       [7, 8]])
>>> data[:,1]
array([2, 4, 6, 8])
Das ist doch, was du wolltest, oder?

Dabei erzeugt Numpy kein neues Array, sondern einen View auf die gefilterten Elemente. Das heißt, sie werden referenziert, aber nicht tatsächlich in eine neue Datenstruktur kopiert. Das kannst du hier in der Note-Box auch gerne nachlesen.
NWA
User
Beiträge: 48
Registriert: Mittwoch 3. Februar 2021, 11:40

Ja, diesen view benötige ich tatsächlich. Aber ich muss das Feld ständig verändern. Angeblich wird ein numpy-Feld neu kopiert, wenn etwas hinzugefügt oder entfernt wird. Dazu habe ich folgendes gefunden:

Hiervon ist allerdings abzuraten, da bei jeder Ausführung von append eine Kopie des NumPy-Arrays erstellt wird. (https://gertingold.github.io/pythonnawi/numpy.html)
Benutzeravatar
snafu
User
Beiträge: 6894
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Aber brauchst du denn append? Was genau möchtest du denn verändern?

Es ist z. B. möglich, alle Elemente des Views auf einen Schlag zu ändern, was sich dann immer auch auf die Original-Struktur auswirkt:

Code: Alles auswählen

>>> data[:,1] = 0
>>> data
array([[1, 0],
       [3, 0],
       [5, 0],
       [7, 0]])
Aber auch andere Modifikationen sind möglich. Probiere es einfach mal in der Python-Shell aus. :)
Sirius3
User
Beiträge: 18317
Registriert: Sonntag 21. Oktober 2012, 17:20

@NWA: was ist Dein Problem? Beschreibe vollständig und verständlich.
NWA
User
Beiträge: 48
Registriert: Mittwoch 3. Februar 2021, 11:40

Das Problem ist schon gelöst. numpy kopiert bei Veränderungen das array. Das kommt aus Performanz-Gründen nicht in Frage. Ich werde deshalb Listen verwenden.

Append brauche ich, weil ich eine Ringliste habe, welche immer in der Größe angepasst werden muss. Wenn numpy ständig das Feld kopiert, dann wäre der Rechner nur damit beschäftigt.
Benutzeravatar
__blackjack__
User
Beiträge: 14209
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@NWA: Das hast Du *ausprobiert*, oder gehst Du einfach davon aus? Du hast keine ”Ringliste” wenn Du nur `append()` verwendest. Wenn Du aber aus der Liste am Anfang Elemente raus löschen solltest: rate was dann passiert. Tipp: hat was mit kopieren zu tun.
“Every thinking person fears nuclear war and every technological nation plans for it. Everyone knows
it's madness, and every country has an excuse.” — Carl Sagan, Cosmos, Episode 13: Who Speaks for Earth?
Sirius3
User
Beiträge: 18317
Registriert: Sonntag 21. Oktober 2012, 17:20

@NWA: wie sieht Dein Code aus? Wie hast Du die Performanz gemessen? Wie groß ist Deine Ringliste?
Pedroski55
User
Beiträge: 25
Registriert: Freitag 25. Juli 2025, 00:20

Was ist schlimm an einem direkten Zugriff auf a?

Code: Alles auswählen

a = [[1,2],[3,4],[5,6],[7,8]]
print(a[1])
>> [3, 4]
NWA
User
Beiträge: 48
Registriert: Mittwoch 3. Februar 2021, 11:40

Für den Börsenhandel habe ich eine bereits funktionierende Ringliste erstellt. Es kommen unzyklisch bis zu 100 Werte in der Sekunde. Ein Zeiger zeigt immer auf den aktuell zu schreibenden Index. Die Liste soll immer eine minimale und maximale Grösse einhalten. Die Grösse wird zur Laufzeit ermittelt und kann bis 100 000 Elemente beinhalten. Gelöscht oder hinzugefügt werden Elemente nur, wenn der Zeiger auf das letzte Element zeigt. Für jeden ankommenden Kurs wird in die äussere Liste eine innere Liste geschrieben, welche Zeit, Kurs und weitere Parameter beinhaltet.

Code: Alles auswählen

a = [[1,2],[3,4],[5,6],[7,8]]
Ich möchte aus dieser Ringliste eine Teilliste bestimmter Elemente der inneren Liste meinem matplotlib-Diagramm direkt übergeben. Der beste Ansatz wäre slicing gewesen. Listen unterstützen aber kein slicing der äusseren Liste.

Code: Alles auswählen

print(a[0:2][1])

>> [3, 4]
Numpy unterstützt aber slicing der äusseren Liste. Leider ist es trotzdem ungeeignet, da bei jeder Änderung das Feld kopiert wird.

Die Performanz habe ich noch nicht gemessen. Dennoch ist das ständige Kopieren ein Ausschlusskriterium um numpy zu verwenden. Als Lösung wollte ich für das Diagramm eine zweite eindimensionale Liste erstellen, welche dann an das Diagramm übergeben wird.
Pedroski55
User
Beiträge: 25
Registriert: Freitag 25. Juli 2025, 00:20

Listen unterstützen aber kein slicing der äusseren Liste.
Wirklich?

Code: Alles auswählen

a = [[1,2],[3,4],[5,6],[7,8]]
b = a[0:2]
b
[[1, 2], [3, 4]]
NWA
User
Beiträge: 48
Registriert: Mittwoch 3. Februar 2021, 11:40

Das ist die äussere Liste.

Jetzt versuch mal aus den inneren Listen immer das nullte Element auszugeben:

Code: Alles auswählen

print(a[0:2][0])
Benutzeravatar
Kebap
User
Beiträge: 780
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

NWA hat geschrieben: Dienstag 30. September 2025, 07:51 Jetzt versuch mal aus den inneren Listen immer das nullte Element auszugeben
Okay :mrgreen:

Code: Alles auswählen

a = [[1,2],[3,4],[5,6],[7,8]]
b = [c[0] for c in a[0:2]]
print(b)
# [1, 3]
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
NWA
User
Beiträge: 48
Registriert: Mittwoch 3. Februar 2021, 11:40

Das geht auch. Aber dann durchlaufe ich wieder und jedesmal die ganze Liste.

Ich frage mich aber, ob beim slicing wieder eine Teilliste erstellt wird. Aber selbst wenn das äussere slicing funktionieren sollte, wird die Ringliste jedesmal komplett durchlaufen.

Ich denke das Beste ist, wenn ich für die Übergabe zum Diagramm zwei neue Ringlisten anlege, welche bei jedem Durchlauf ein Element hinzufügt und das Ende dynamisch kappt.

Vielen Dank für eure Hinweise.
Benutzeravatar
__blackjack__
User
Beiträge: 14209
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich denke das Beste ist es erst einmal korrekt zu lösen, und dann zu messen wo zu viel Zeit verbraucht wird. Oder ob da überhaupt zu viel Zeit verbraucht wird.
“Every thinking person fears nuclear war and every technological nation plans for it. Everyone knows
it's madness, and every country has an excuse.” — Carl Sagan, Cosmos, Episode 13: Who Speaks for Earth?
Sirius3
User
Beiträge: 18317
Registriert: Sonntag 21. Oktober 2012, 17:20

@NWA: so wie Du Deine "Ringliste" beschreibst, wird immer nur das älteste Element überschrieben. Das geht natürlich auch mit numpy-Arrays ohne Kopie. Man muß halt nur das initiale Array groß genug anlegen.
Bei Listen wird auch, je nach Bedarf kopiert.
Benutzeravatar
snafu
User
Beiträge: 6894
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

NWA hat geschrieben: Dienstag 30. September 2025, 08:59 Aber selbst wenn das äussere slicing funktionieren sollte, wird die Ringliste jedesmal komplett durchlaufen.
Weiter oben war deine Anforderung, dass aus jeder Unterliste das zweite Element genommen werden soll. Dafür muss selbstverständlich die komplette Liste durchlaufen werden. Aber das stört dich nun auch? Es kommt mir ein bisschen vor, als weißt du selber nicht genau, was du eigentlich willst. Umso schwieriger ist es dann, dir sinnvoll helfen zu können...
Antworten