Array aufteilen

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.
Bine2706
User
Beiträge: 13
Registriert: Samstag 30. Juni 2018, 18:09

Hallo zusammen =)
ich bin neu hier und lerne gerade Python.
Doch nun stehe ich vor einem Problem, bei dem ich einfach nicht weiterkomme.

Ich habe aus einer Textdatei Koordinaten von 26 Standorten (=koordinaten_alleStandorte) eingelesen und daraus eine Distanzmatrix (=fahrtkostenmatrix) erstellt. Nun ist es jedoch so, dass ich ein Array benötige mit 26 Elemente pro Array und 26 Zeilen (=fahrtkosten).

Wenn ich das mit einer for-Schleife versuche aufzuteilen (die im Moment rauskommentiert ist), bringt er mit in Zeile eukliddist = jedoch den Fehler "'int' object is not subscriptable", obwohl er mir die werte ausgibt wenn ich die for-Schleife rauskommentiere. Woran kann das liegen? Oder gibt es eine andere Möglichkeit die Liste fahrtkostenmatrix aufzuteilen?

koordinaten_alleStandorte = koordinaten_plattform+koordinaten_satellit+koordinaten_kunden
fahrtkosten = []
fahrtkostenmatrix = []
for i in koordinaten_alleStandorte:
for j in koordinaten_alleStandorte:
eukliddist = math.sqrt((int(j[0])-int(i[0]))**2+(int(j[1])-int(i[1]))**2)
werte_fahrtkosten = math.ceil(eukliddist*100)
fahrtkostenmatrix.append(werte_fahrtkosten)
# for i in range(0,len(fahrtkostenmatrix),anzahlStandorte):
# fahrtkosten = [fahrtkostenmatrix[i:i+anzahlStandorte]]
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Du machst Dir mit der auskommentierten for-Schleife ja auch die Variable i kaputt. Was willst Du mit der for-Schleife überhaupt bewirken?
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

versuchs mal so

Code: Alles auswählen

import math

koordinaten_plattform = [[2,3], [3,4], [2,5]]
koordinaten_satellit = [[5,7], [2,8], [3,7]]
koordinaten_kunden = [[8,2], [4,6], [7,4]]

koordinaten_alleStandorte = koordinaten_plattform + koordinaten_satellit + koordinaten_kunden

fahrtkostenmatrix = []
for row in koordinaten_alleStandorte:
    reihe = []
    for column in koordinaten_alleStandorte:
        eukliddist = math.sqrt((int(column[0]) - int(row[0])) ** 2 + (int(column[1]) - int(row[1])) ** 2)
        werte_fahrtkosten = math.ceil(eukliddist * 100)
        reihe.append(werte_fahrtkosten)
    fahrtkostenmatrix.append(reihe)

for reihe in fahrtkostenmatrix:
    print(reihe)
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
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

und diesen Code

Code: Alles auswählen

fahrtkostenmatrix = []
for row in koordinaten_alleStandorte:
    reihe = []
    for column in koordinaten_alleStandorte:
        eukliddist = math.sqrt((int(column[0]) - int(row[0])) ** 2 + (int(column[1]) - int(row[1])) ** 2)
        werte_fahrtkosten = math.ceil(eukliddist * 100)
        reihe.append(werte_fahrtkosten)
    fahrtkostenmatrix.append(reihe)
ersetzt man pythonisch mit Hilfe einer Funktion durch eine sogenannte "list comprehension" in

Code: Alles auswählen

def errechne_fahrtkosten(x, y):
    return math.ceil(math.sqrt((int(y[0]) - int(x[0])) ** 2 + (int(y[1]) - int(x[1])) ** 2) * 100)

fahrtkostenmatrix = [[errechne_fahrtkosten(row, column) for column in koordinaten_alleStandorte] for row in koordinaten_alleStandorte]
Edit:
und wenn man die Funktion errechne_fahrtkosten sonst nicht benötigt, könnte man sie durch eine anonyme Lambda-Funktion ersetzen.
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
Bine2706
User
Beiträge: 13
Registriert: Samstag 30. Juni 2018, 18:09

Der Teil des Codes ist Teil eines Codes mit dem ich aus einer Text-Datei einlese, der bereits mit einer Funktion verknüpft ist.

Ich habe 3 Ebenen mit einer unterschiedlichen Anzahl an Standorten: P (=koordinaten_plattform), S (=koordinaten_satellit) und K (=koordinaten_kunden)
(hier beispielhaft mit nur einem Standort pro Ebene -> anzahlStandorte = 3)
und will daraus eine Distanzmatrix erstellen.
In meinem Code dient fahrtkostenmatrix nur als Zwischenergebnis, das ich danach weiterverarbeiten wollte.
Mit meinem Code oben klappt jedoch nur folgende Ausgabe:

fahrtkostenmatrix = [DistP-P, DistP-S, DistP-K, DistS-P, DistS-S, DistS-K, DistK-P, DistK-S, DistK-K]

eigentlich benötige ich folgende Ausgabe benötige:

fahrtkosten = [[DistP-P, DistP-S, DistP-K], [DistS-P, DistS-S, DistS-K], [DistK-P, DistK-S, DistK-K]]

(immer mit der Dimension anzahlStandorte x anzahlStandorte)
und das wollte ich mit der auskommentierten for-Schleife machen, aber leider erfolglos.

Eventuell ist auch meine Herangehensweise falsch.
Denn zusätzlich müssten noch alle Distanzen zwischen P und S (also DistP-S und DistS-P) und zwischen S und S (also DistS-S) nicht mit 100 multipliziert werden, sondern mit 200. Aber soweit bin ich leider noch nicht gekommen.

Und die Variable fahrtkosten muss auch außerhalb der Schleife verwendbar sein, dh. das muss nicht nur ausgegeben werden sondern die Variable muss so belegt werden. Das print mache ich immer zur Hilfe um zu schauen ob es richtig eingelesen hat :D
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ThomasL: Die Argumentnamen `x` und `y` sind aber mehr als unglücklich gewählt.

@Bine2706: Die herangehensweise ist in der Tat falsch. Warum erstellst Du die `fahrtkostenmatrix` überhaupt? Wie man diesen Zwischenschritt umgeht hat ThomasL ja bereits gezeigt.

Namen wie `i` und `j` sollte man übrigens nur an ganze Zahlen binden die dann als Index verwendet werden. Nicht für irgendwelche anderen Werte. Das ist *sehr* verwirrend.

Ausserdem solltest man Listen nicht als Arrays bezeichnen. Es gibt in Python, beziehungsweise aus Bibliotheken von Drittanbietern, Datentypen die Arrays heissen. In Python ist mit dem Begriff Array in der Regel ein Arraydatentyp aus den Numpy-Package gemeint. In selteneren Fällen ein `bytearray`-Objekt oder ein `ctypes.Array` aus der Standardbibliothek. Und in sehr seltenen Fällen ein `array` aus dem gleichnamigen Modul in der Standardbibliothek.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

__blackjack__ hat geschrieben: Sonntag 1. Juli 2018, 00:36 @ThomasL: Die Argumentnamen `x` und `y` sind aber mehr als unglücklich gewählt.
Stimmt, aber ich sage mir immer, Namen sind Schall und Rauch,
ich hätte sie auch stan und laurel nennen können :lol:
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
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

@Bin2706
So ganz werde ich aus deinen Ausführungen nicht schlau.
Kannst du uns genauer beschreiben, wie deine Koordinaten Datenstrukturen (die du einliest) aussehen,
und wie dann nach der Berechnung der Distanzen die Datenstruktur des gewünschten Endergebnis aussehen soll.
Erkläre uns den Algorithmus den du coden willst.
Eventuell helfen dir diese Überlegungen selbst zu einer Lösung zu kommen.
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
Bine2706
User
Beiträge: 13
Registriert: Samstag 30. Juni 2018, 18:09

Entschuldige bitte, ich bin mit den Begriffen noch unsicher und daher ist es sehr schwer zu erklären =)
Ich versuche es nochmal:

Ich muss ein Optimierungsproblem in Python implementieren und mit dem Solver Gurobi lösen.
Daher lese ich im ersten Schritt die Daten, unter anderem die Koordinaten der Standorte, aus einer Textdatei aus.
Es gibt drei Mengen von Standorten, die bei mir als Plattformen, Satelliten und Kunden bezeichnet sind.
Die Koordinaten sind in der Textdataei in zwei Spalten angegeben, 1. Spalte x-Koordiante, 2. Spalte y-Koordinate, pro Zeile ein Standort.
Die Spalten sind mit einem Tab getrennt.
Die Anzahl an Standorte, dh die Anzahl an Zeilen in der Text-Datei, variiert je nach Instanz, muss es so implementiert sein, dass es bei jeder länge funktioniert.

Im ersten Schritt, den ich bereits im Einlesen-Teil implementiert habe, werden die Daten eingelesen, mit folgendem Code:

koordinaten_satellit = []
for line in range(4, anzahl_satelliten+4):
tupel = lines[line].split('\t')
koordinaten_satellit.append((int(tupel[0]),int(tupel[1])))

Die Ausgabe ist hierbei folgende:

koordinaten_plattform = [(0, 0)]
koordinaten_satellit = [(6, 7), (19, 44)] (Satellit S1 und S2)
koordinaten_kunden = [(20, 35), (8, 31), (29, 43), (18, 39)] (Kunde K1, K2, K3 und K4)

Dies dient lediglich als Zwischenschritt, da ich es nicht geschafft habe, direkt beim Einlesen die Distanzkostenmatrix (also die Fahrtkosten) auszugeben

Deswegen nun die oben gepostete Schleife um die Matrix zu berechnen.
Die Kosten berechnen sich mit euklidische Distanz*100

Ich habe gerade etwas umgestellt, daher brauche ich als Ergebnis nun zwei Kostenmatrizen, die aber die selbe Struktur haben sollen (die Kunden ignoriere ich mal und zeige hier nur eine von beiden, nämlich die zwischen der Plattform und den Satelliten):
fahrtkosten = [[fahrtkosten P - P, fahrtkosten P - S1, fahrtkosten P - S2], [fahrtkosten S1 - P, fahrtkosten S1 - S1, fahrtkosten S1 - S2], fahrtkosten S2 - P, fahrtkosten S2 - S1, fahrtkosten S2 - S2]]

Und die Variable fahrtkosten sollte danach mit der Matrix belegt sein, also es geht mir nicht um die Ausgabe, sondern darum das ich mit der Variablen weiterrechnen kann.

Ich hoffe ich konnte es nun verständlich erklären =) denke über diese Stelle schon über ne Woche nach und komme einfach nicht weiter =(
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Bine2706: das war ja noch der verständliche Teil, zu dem Du auch schon selbst die Lösung hattest. Einlesen und Distanzkostenmatrix berechnen sind auch zwei getrennte Schritte, so dass man das nicht versuchen sollte, ineinander zu vermischen. Wo hast Du also jetzt konkret ein Problem?
Bine2706
User
Beiträge: 13
Registriert: Samstag 30. Juni 2018, 18:09

Achso, sorry
Gut dann hab ich es richtig gemacht, einlesen funktioniert.

Mein Problem steht doch oben?
Ich komme nicht auf die Ausgabe
Fahrtkosten = [[...], [...], [...]] sondern nur auf [..........]

Die Ausgabe von Thomas liefert [...] [...] [...] in jeweils net neuen Zeile, scheint mir als wäre es ne reine Ausgabe und kein belegen der Variablen
Bine2706
User
Beiträge: 13
Registriert: Samstag 30. Juni 2018, 18:09

Lösung habe ich dazu leider keine selber gefunden
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Lösung von ThomasL liefert schon das, was Du haben willst, die Ausgabe kommt ja einfach danach. Das ergibt eine verschachtelte Liste:

Code: Alles auswählen

def errechne_fahrtkosten(a, b):
    return math.ceil(((a[0] - b[0]) ** 2 + (a[1] -b[1]) ** 2) ** 0.5 * 100)

fahrtkostenmatrix = [[errechne_fahrtkosten(a, b) for a in koordinaten_alleStandorte]
    for b in koordinaten_alleStandorte]
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bine2706: ThomasL gibt nicht die verschachtelte Liste aus sondern in einer Schleife jedes einzelne Element, dann natürlich in einer eigenen Zeile. Aber die Struktur hat natürlich die Form [[…], […], […]]. Was Du durch die Ausgabe der gesamten Struktur aber auch einfach selbst hättest feststellen können.

Und Du musst solange Python Grundlagen üben bis Du das auch am Code ablesen kannst. Das kann Dir keiner abnehmen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Bine, ich habe mal die kunden weggelassen und am Ende ein einfaches print() eingebaut.
Kannst du das mal nachvollziehen ob das so ok ist für dich.

Code: Alles auswählen

import math

def errechne_fahrtkosten(x, y):
    return math.ceil(math.sqrt((int(y[0]) - int(x[0])) ** 2 + (int(y[1]) - int(x[1])) ** 2) * 100)

koordinaten_plattform = [(0, 0)]
koordinaten_satellit = [(6, 7), (19, 44)]
# koordinaten_kunden = [[8,2], [4,6], [7,4]]

koordinaten_alleStandorte = koordinaten_plattform + koordinaten_satellit

fahrtkostenmatrix = [[errechne_fahrtkosten(row, column) for column in koordinaten_alleStandorte] for row in koordinaten_alleStandorte]

print(fahrtkostenmatrix)

# fahrtkostenmatrix ist jetzt  [[0, 922, 4793], [922, 0, 3922], [4793, 3922, 0]]
# und das entspricht  [[P - P, P - S1, P - S2], [S1 - P, S1 - S1, S1 - S2], [S2 - P,  S2 - S1, S2 - S2]]   und das ist das was du willst
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
Bine2706
User
Beiträge: 13
Registriert: Samstag 30. Juni 2018, 18:09

@Thomas: Vielen vielen Dank, das klappt. Nun habe ich auch verstanden das das oben ja schon genau dasselbe war und ich nur die letzte for-Schleife hätte ersetzen müssen. Sorry =)

Wie gesagt, python ist meine erste Programmiersprache und es ist am Anfang recht viel was da alles Neues auf einen zukommt. Aber ich habe aus dieser Frage sehr viel gelernt, vielen Dank an alle =) =)
Bine2706
User
Beiträge: 13
Registriert: Samstag 30. Juni 2018, 18:09

jetzt hab ich leider doch nochmal ein Problem =(
das Ausgeben hat super geklappt, und nun habe ich die Funktion in den restlichen Code eingebaut. Es kommt nun jedoch die Fehlermeldung "int" is not iterable. Das heißt ja python sieht die fahrtkostenmatrix als ein int-Wert und nicht als Liste oder? und wie kann ich sie iterabel machen?
Bisher habe ich bei Listen immer mit .append gearbeitet, da habe ich jedoch aus einer .txt eingelesen und die Werte nicht erst in Python berechnet
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast wahrscheinlich wieder die selbe Variable für zwei verschiedene Dinge benutzt. Aber ohne den Code zu kennen, kann man da nicht helfen.
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Nabend Bine,
int ist ja auch nicht iterable, die fahrtkostenmatrix die im letzten Code erzeugt wurde aber doch.
Also muss bei deinem "Einbau" was nicht richtig sein.
Zeig uns den Code, nur dann haben wir was mit dem wir arbeiten und helfen können.
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
Bine2706
User
Beiträge: 13
Registriert: Samstag 30. Juni 2018, 18:09

@Sirius: nein habe ich nicht.
Das scheint damit zu tun zu haben ob ich die Funktion in eine andere Datei schreibe und und sie dann in meiner main-Datei aufrufe oder ob ich alles in einer Datei habe.

So ist alles in einer Datei und es funktioniert:

def errechne_fahrtkosten_ersterStufe(x, y):
return math.ceil(math.sqrt((int(y[0])-int(x[0]))**2+(int(y[1])-int(x[1]))**2)*200)
fahrtkosten_ersterStufe = [[errechne_fahrtkosten_ersterStufe(reihe, spalte) for spalte in koordinaten_standorte_ersterStufe] for reihe in koordinaten_standorte_ersterStufe]

So ist es in zwei Dateien. Das Übertragen klappt, also ich kann zb. fahrtkosten_ersterStufe printen, aber eben nicht damit weiterrechnen (mit Gurobi)

MAIN-DATEI:
fahrtkosten_ersterStufe = [[errechne_fahrtkosten_ersterStufe(reihe, spalte) for spalte in koordinaten_standorte_ersterStufe] for reihe in koordinaten_standorte_ersterStufe]

DATEI MIT FUNKTION:
def errechne_fahrtkosten_ersterStufe(x, y):
return math.ceil(math.sqrt((int(y[0])-int(x[0]))**2+(int(y[1])-int(x[1]))**2)*200)
Antworten