3-dimensionales Array sortieren

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.
Antworten
PythonBeginner2018
User
Beiträge: 4
Registriert: Donnerstag 31. Januar 2019, 18:19

Liebe Spezialistinnen und Spezialisten,

ich habe vor ein paar Wochen angefangen Python zu lernen. Komme aber nun nicht mehr weiter.
Ich versuche ein 3-dimensionales Array zu sortieren. Über 2d-Arrays gibt es einiges im Internet, aber die Übertragung auf 3d-Arrays gelingt mir nicht. Die Python- und Numpy-Referencen bringen mich auch nicht weiter.

Ich möchte gern die stündlichen Temperaturen über 100 Tage für jeden einzelnen Tag sortieren. Dazu habe ich die Daten in ein Array mit der Dimensionierung temperatur(100, 2, 25) und dem Datentyp Integer32 gepackt. Für den 1. Tage sieht das Array wie folgt aus:

[20180101, 20180101] Zeile 0 enthält zweimal das Datum 1.1.2018
[1, 18] Zeile 1 enthält die Stunde 1 und die Temperatur 18 Grad
[2, 18] Zeile 2 enthält die Stunde 2 und die Temperatur 18 Grad
[3, 19] Zeile 3 enthält die Stunde 3 und die Temperatur 19 Grad usw.
....
[12, 23]
[13, 24]
....
[22, 19]
[23, 18]
[24, 17]

Nun möchte ich für jeden Tag die Temperaturen auf- bzw. absteigend sortieren und die dazugehörige Stunde mit sortieren, damit das Ergebnis so aussieht:

[20180101, 20180101]
[13, 24]
[12, 23]
[22, 19]
....
[23, 18]
[24, 17]

Ich hatte die Hoffnung, dass es analog dem Sortieren von 2-dimensionalen Arrays funktionieren würde, nur klappt es leider nicht.

Code: Alles auswählen


import numpy as np

# 3 Tage, 2 Spalten für 24 Stunden und 24 Temperaturwerte

t = np.array([[[20190101, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
               [20190101, 18, 18, 19, 19, 17, 16, 18, 17, 19, 20, 20, 20, 21, 22, 20, 19, 20, 20, 21, 22, 23, 22, 22,
                21]],
              [[20190102, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
               [20190102, 18, 18, 19, 19, 17, 16, 18, 17, 19, 20, 20, 20, 21, 22, 20, 19, 20, 20, 21, 22, 23, 22, 22,
                21]],
              [[20190103, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
               [20190103, 18, 18, 19, 19, 17, 16, 18, 17, 19, 20, 20, 20, 21, 22, 20, 19, 20, 20, 21, 22, 23, 22, 22,
                21]]], dtype=np.int32)

print(t)
print("Anzahl Dimensionen:", t.ndim)

x=input("weiter?")

for i in range(0, 3):
    t = t[np.argsort(t[i, 1, 1:24])]

print("--------sortiert-------------")
print(t)

aber leider bekomme ich den Fehler:

Traceback (most recent call last):
File "E:/Dokumente/PyCharmProjects/Lz_01/Test_Sort.py", line 27, in <module>
t = t[np.argsort(t[i, 1, 1:24])]
IndexError: index 5 is out of bounds for axis 0 with size 3

Process finished with exit code 1


Kann mir bitte jemand helfen?
Vielleicht kann mir jemand auch Tipps geben wo das Sortieren möglichst einfach und verständlich erklärt wird. 1- und 2-dimensionale Arrays sind kein Problem, aber sobald es 3- und mehr-dimensional wird es schwierig.

Vielen Dank im voraus.
Dieter
ArtooDetoo
User
Beiträge: 60
Registriert: Dienstag 4. Dezember 2018, 16:57

So wie ich das sehe, hast du doch einfach ein 2D-Array für jeden einzelnen Tag, das du sortieren musst. Und 2D-Arrays sind ja, wie du sagst, kein Problem.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum generierst Du ein `t` in einer Schleife, machst aber mit diesem t nichts mehr?
Das Array ist schlecht definiert. In der ersten Spalte scheinst Du ein Datum zu haben.
Was Du eigentlich hast sind 2-Tuple von Zeit und Temperatur über einen Index Datum, die Du sortieren willst. Dafür bietet sich Pandas besser als numpy an.
PythonBeginner2018
User
Beiträge: 4
Registriert: Donnerstag 31. Januar 2019, 18:19

Hallo ArtooDetoo und Sirius3
Vielen Dank für Eure schnelle Antwort.

@ArtooDetoo
Wenn ich Dich richtig verstehe muss ich jeden Tag in ein 2-dimensionales Array kopieren, sortieren und wieder zurückkopieren. Ich hatte gehofft, dass es eine einfachere und elegantere Lösung geben würde. So ähnlich, wie ich es in der leider nicht funktionierenden for-Schleife, angedacht hatte. Aber anscheinend beherrscht Numpy nur das Sortieren von 2-dimensionalen Arrays.

@Sirius3
Ich verstehe Deine Frage "Warum generierst Du ein `t` in einer Schleife, machst aber mit diesem t nichts mehr?" nicht. Mit der for-Schleife versuche ich für jeden i-ten Tag die Temperaturen zu sortieren.
Auf Deinen Rat hin werde ich mich mal mit Pandas beschäftigen, vielleicht bringt mich das weiter.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@PythonBeginner2018: Du kopierst alles in ein neues Array, machst aber dann nichts damit.

Code: Alles auswählen

for day in t:
    ind = np.argsort(day[1, 1:])
    day[:, 1:] = day[:, 1:][:, ind]
[/python|
Wie Du siehst, macht Deine seltsame Wahl der Datenstruktur alles unnötig kompliziert.
Was willst Du denn weiter damit machen?
PythonBeginner2018
User
Beiträge: 4
Registriert: Donnerstag 31. Januar 2019, 18:19

Hallo Sirius3,

vielen Dank für Deine Hilfe.

Mit der Anweisung:

Code: Alles auswählen

t = t[np.argsort(t[i, 1, 1:24])]

hatte ich die Hoffnung ich könnte in einer for-Schleife über alle Tage iterieren und innerhalb jeden Tages nach einer Spalte sortieren. Ich hatte im Netz diese Anweisung gefunden

Code: Alles auswählen

erg = erg[np.argsort(erg[:,1])]

und gehofft ich könnte sie einmal um eine 3. Dimension erweitern und zum anderen die zu sortierenden Zeilen auf 1 bis 24 beschränken, also ohne die Nullte Zeile in der das Datum steht. Da war ich offensichtlich auf der falschen Spur. Inzwischen habe ich es so gemacht, dass ich die 24 Temperaturwerte (ohne das Datum) in ein 2-dimensionales Array kopiere und es dort sortiere. Das funktioniert auch, ist hat nicht so schön.

Deinen vorgeschlagenen Code verstehe ich leider "noch" nicht, weil ich mich mit Listen etc. in Python noch nicht so recht auskenne. Ich habe bisher viel mit VBA for Excel gemacht, dort sind Arrays meiner Meinung nach sehr benutzerfreundlich konzipiert. Deshalb war ich froh die Arrays von Numpy gefunden zu haben und hatte gehofft dort möglichst ähnlich wie in VBA verfahren zu können. Ich werde mich also zunächstmal mit den Listen und insbesondere mit Pandas Series beschäftigen um das zu kapieren.

Zu Deiner Frage was ich damit machen will. Es geht einfach nur darum anhand eines Problems Python zu lernen. Wenn ich mit den Dateistrukturen zurecht komme, möchte ich als nächstes die Daten mit mathplotlib darstellen.
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@PythonBeginner2018: Ich weiss nicht ob ein sehr Numpy-lastiges Problem der beste Einstieg ist um *Python* zu lernen, weil Numpy ja a) darauf ausgelegt ist möglichst viel *nicht* in Python-Code zu lösen, und b) dadurch eben recht wenig Python-spezifisches in solchen Programmen vorkommt.

Arrays in VBA dürften wohl eher Listen in Python entsprechen und Numpy-Arrays haben AFAIK kein entsprechendes Gegenstück in VBA.

Eine praktische Eigenschaft von Python ist hier IMHO das man vieles mit Beispieldaten interaktiv ausprobieren kann. Entweder in der normalen Python-Shell oder in aufgebohrten Shells wie IPython oder Jupyter Notebooks. Da kannst Du mit den Daten und Teilausdrücken ein wenig herum spielen um ein besseres Verständnis zu bekommen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Code: Alles auswählen

# 3 Tage, 2 Spalten für 24 Stunden und 24 Temperaturwerte
t = np.array([[[20190101, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
               [20190101, 18, 18, 19, 19, 17, 16, 18, 17, 19, 20, 20, 20, 21, 22, 20, 19, 20, 20, 21, 22, 23, 22, 22, 21]],
              [[20190102, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
               [20190102, 18, 18, 19, 19, 17, 16, 18, 17, 19, 20, 20, 20, 21, 22, 20, 19, 20, 20, 21, 22, 23, 22, 22, 21]],
              [[20190103, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
               [20190103, 18, 18, 19, 19, 17, 16, 18, 17, 19, 20, 20, 20, 21, 22, 20, 19, 20, 20, 21, 22, 23, 22, 22, 21]]], dtype=np.int32)
Werden deine Daten so generiert oder wieso hat das Array dieses Format?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
PythonBeginner2018
User
Beiträge: 4
Registriert: Donnerstag 31. Januar 2019, 18:19

Mit so einem Echo meiner Anfrage hatte ich garnicht gerechnet. Vielen Dank für Eure Hinweise.

@Sirius3. Ich habe gerade Deinen Code ausprobiert. Er funktioniert fantastisch, eine echt geniale Lösung. Da wäre ich nie drauf gekommen. Nur ich verstehe nicht wie er funktioniert. Da fehlen mir noch zu viele Grundkenntnisse.

@__blackjack__. Ich hatte bisher den Eindruck, dass Python-Listen nicht den VBA-Arrays entsprechen und bin dann auf Numpy-Arrays gestoßen. Aber die Numpy-Arrays sind in der Handhabung doch etwas anders. Ich werde mich auf jeden Fall mit den Listen in Python noch intensiver beschäftigen um ein Gefühl für deren Handhabung zu bekommen. Nebenbei, ich benutze PyCharm und bin ganz zufrieden damit.

@TomasL. Die Daten habe ich aus einer Excel-Tabelle, die ich als csv-Datei abgespeichert und dann eingelesen habe. Sie liegen in folgendem Format vor (Datum und 24 Temperaturwerte):
20190101; 18, 18, 19, ...., 17
Die Stunden habe ich dann noch dazugefügt. Deshalb sehen die Daten so aus. Da ich vermute, dass man Dateien nicht hochladen kann, habe ich 3 Beispiel-Datensätze im Code platziert. Sicherlich gibt es bzgl. Dateistruktur noch bessere Lösungen, die Python-gerechter sind.
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@PythonBeginner2018: Von der Implementierung her sind Numpy-Array vielleicht näher an VBA-Arrays, aber sie haben halt die zusätzlichen Methoden für wissenschaftliches Rechnen und Listen werden für das benutzt für das man in VBA Arrays verwendet. Listen sind in Python der Sequenzdatentyp den man für alles mögliche verwendet, solange man keine spezielleren Eigenschaften benötigt, so wie Arrays das in VBA sind.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@PythonBeginner2018: ob das eine gute Datenstruktur ist, kann man erst sagen, wenn wir wissen, wie Du die Daten weiter verarbeiten willst. Und damit Du das selbst erfahren kannst, mußt Du erst die verschiedenen Grunddatentypen von Python kennen lernen. Laß Dich auf die Sprache ein und versuche nicht, etwas, das Du aus VBA kennst, blind zu übertragen.
Antworten