Addition von Single Arrays

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
Hanso
User
Beiträge: 7
Registriert: Mittwoch 15. Februar 2017, 10:48

Hallo Leute,

ich habe erst vor kurzer Zeit angefangen mich mit Python zu beschäftigen. Ich glaube mein Problem ist relativ simpel, allerdings konnte ich weder durch googeln, Forum-Suche oder im Manual eine Antwort finden, die bei mir funktioniert hat.

Mein Python-Skript liest aus einer FE-Simulation die Verschiebung (U2) an zwei Knoten (VO und VU) zu jedem Zeitschritt aus. Ich möchte nun die Differenz dieser beiden Verschiebungen für jeden Zeitschritt in Python bestimmen, und als "Verschiebung" als npy-file abspeichern.
Der entsprechende Code (ohne Subtraktion) sieht wie folgt aus:

Code: Alles auswählen


U2 = []
for i in range(1,anz_frames+1):
	UValues = odb.steps['Step-1'].frames[i].fieldOutputs['U'].getSubset(region=odb.rootAssembly.nodeSets['VO']).values	
	
	for k in UValues:
		U2.append([k.dataDouble[1]])
numpy.save('VerschiebungO.npy',U2)


U2 = []
for i in range(1,anz_frames+1):
	UValues = odb.steps['Step-1'].frames[i].fieldOutputs['U'].getSubset(region=odb.rootAssembly.nodeSets['VU']).values	
	
	for k in UValues:
		U2.append([k.dataDouble[1]])
numpy.save('VerschiebungU.npy',U2)

Den Abschnitt mit der Subtraktion habe ich mit verschiedenen Möglichkeiten versucht, z.B.

Code: Alles auswählen

Verschiebung = VerschiebungO - VerschiebungU
numpy.save('Verschiebung,U2)
oder

Code: Alles auswählen

np.subtract(VerschiebungO, VerschiebungU)
numpy.save('Verschiebung,U2)
Ich habe zahlreiche Kombinationen und Befehle ausprobiert, leider ohne Erfolg. Kann mir bitte jemand weiterhelfen, mit welchem Befehl es am besten klappen müsste?
Vielen Dank im Vorraus für jegliche Hilfe.
Zuletzt geändert von Anonymous am Mittwoch 15. Februar 2017, 12:14, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Hanso: Wie sind denn `VerschiebungO` und `VerschiebungU` definiert? Welche Fehlermeldung bekommst Du? Das man Listen nicht voneinander abziehen kann? Das sollte eigentlich nicht weiter verwundern.

Du könntest aus den Listen Numpy-Arrays erstellen. *Die* kann man dann voneinander abziehen.

Warum hängst Du an die Listen *Listen* mit nur *einem* Element an? Falls es da um die Dimensionen geht, also (n,1) statt (n,) mit `n` der Anzahl der Werte, dann sollte man das nach dem erzeugen eines Numpy-Arrays mit `reshape()` erledigen. Da sich dabei an den eigentlichen Daten nichts ändert ist das wesentlich effizienter als für jeden Wert nich eine extra Python-Liste mit eben nur diesem einen Wert als einzigem Element zu erzeugen.

Da steht im Grunde zweimal fast der gleiche Code hintereinander. Das sollte man in eine Funktion auslagern um diesen Code nur einmal schreiben zu müssen.
Hanso
User
Beiträge: 7
Registriert: Mittwoch 15. Februar 2017, 10:48

Danke erstmal für die Antwort.
Das der Code für 2 Listen unnötig lang ist, ist richtig. Ich habe ein Python-Skript vorgegeben und muss es nur abändern, dabei ist es zunächst egal wie kompliziert das ist, und auf diese Weise war es für mich als Neuling am einfachsten zu verstehen.

VerschiebungO und VerschiebungU waren gar nicht definiert, das waren lediglich die Namen der npy-Ausgabedateien. Ich habe jetzt die Definitionen "UValues" und "OValues" erstellt und versucht, das ganze in Arrays umzuwandeln und diese zu subtrahieren.
Mein neuer Code lautet:

Code: Alles auswählen

U2 = []
for i in range(1,anz_frames+1):
	OValues = odb.steps['Step-1'].frames[i].fieldOutputs['U'].getSubset(region=odb.rootAssembly.nodeSets['VO']).values	
	
	for k in OValues:
		U2.append([k.dataDouble[1]])
numpy.save('VerschiebungO.npy',U2)


U2 = []
for i in range(1,anz_frames+1):
	UValues = odb.steps['Step-1'].frames[i].fieldOutputs['U'].getSubset(region=odb.rootAssembly.nodeSets['VU']).values	
	
	for k in UValues:
		U2.append([k.dataDouble[1]])
numpy.save('VerschiebungU.npy',U2)

from numpy import array
a = np.array([OValues])
b = np.array([UValues])
Verschiebung = a - b
numpy.save('Verschiebung.npy',U2)
Leider bekomme ich dabei die Fehlermeldung "Name error: Name 'np' is not defined". Wenn ich anstatt np.array nur Array schreibe, stürzt sogar das Programm ab. Was mache ich bei der Umwandlung falsch?
Zuletzt geändert von Anonymous am Mittwoch 15. Februar 2017, 14:23, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Hanso hat geschrieben:Leider bekomme ich dabei die Fehlermeldung "Name error: Name 'np' is not defined".
Anstatt

Code: Alles auswählen

from numpy import array
...
numpy.save('Verschiebung.npy',U2)
schreib lieber

Code: Alles auswählen

import numpy as np
...
np.save('Verschiebung.npy',U2)
a fool with a tool is still a fool, www.magben.de, YouTube
Hanso
User
Beiträge: 7
Registriert: Mittwoch 15. Februar 2017, 10:48

Danke ich habe das geändert. Allerdings stürzt das Programm (Abaqus CAE) beim Durchlaufen des Programms ab, irgendwas stimmt wohl noch nicht
Hanso
User
Beiträge: 7
Registriert: Mittwoch 15. Februar 2017, 10:48

Ich hab noch weitere Möglichkeiten versucht, aber leider funktioniert nichts davon.

Code: Alles auswählen

from operator import add
map(add, OValues, UValues)
numpy.save('Verschiebung.npy',U2)
oder

Code: Alles auswählen


U2 = []
for i in range(1,anz_frames+1):
	OValues = odb.steps['Step-1'].frames[i].fieldOutputs['U'].getSubset(region=odb.rootAssembly.nodeSets['VO']).values	
	
	for k in OValues:
		U2.append([k.dataDouble[1]])
numpy.save('VerschiebungO.npy',U2)


U2 = []
for i in range(1,anz_frames+1):
	UValues = odb.steps['Step-1'].frames[i].fieldOutputs['U'].getSubset(region=odb.rootAssembly.nodeSets['VU']).values	
	
	for k in UValues:
		U2.append([k.dataDouble[1]])
numpy.save('VerschiebungU.npy',U2)

import numpy as np
vector1 = np.array([OValues])
vector2 = np.array([UValues])
sum_vector = vector1 + vector2
numpy.save('Verschiebung.npy',U2)

Egal wie ich es mache, wenn ich das Script laufen lasse, beendet sich das Programm von selbst und nichts passiert.

Brauche ich noch irgendwelche AddOns / Module für Python um np.array zu verwenden?
Kann es daran liegen dass die Listen nicht korrekt als "OValues" "UValues" definiert sind?

Vielen Dank im vorraus für eine Antwort
Zuletzt geändert von Anonymous am Donnerstag 16. Februar 2017, 14:27, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Hanso hat geschrieben:Egal wie ich es mache, wenn ich das Script laufen lasse, beendet sich das Programm von selbst und nichts passiert.
Wenn ein Python-Programm abstürzt, dann wird auf der Konsole eine nützliche Fehlermeldung ausgegeben: es wird die Programmzeile und die Art des Fehlers ausgegeben. Anhand dieser Fehlermeldung kann der Spezialist oftmals sagen was Falsch gelaufen ist. Hast Du so eine Fehlermeldung bekommen, die Du hier posten könntest?
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

In welcher Umgebung lässt du das Skript laufen? Es ist bei unerwarteten Abstürzen meistens eine gute Idee, das Skript direkt auf der Kommandozeile aufzurufen. Dann kriegt man auch die Fehlermeldung zu sehen.
Hanso
User
Beiträge: 7
Registriert: Mittwoch 15. Februar 2017, 10:48

Ich lasse das Programm in Abaqus/CAE laufen. Wenn ich in Python direkt auf "Run" gehe, wähle ich ebenfalls meine Abaqus odb-Datei und muss das Script von dort starten. Welche Alternative gibt es?

Ich muss allerdings sagen dass das Programm lief, bevor ich den neuen Teil mit der Addition hinzugefügt habe. Auch jetzt läuft das Script einige Sekunden, gibt mir Daten aus - bis zu der Stelle mit der Addition. Abaqus gibt die Meldung "GUI detected error while waiting for ipc Connection to close. Abaqus/CAE Kernel exited with an error." aus.


Ist meine Definition mit "OValues" und "UValues" in Ordnung? Oder gibt es eine kompliziertere, aber sichere Methode für die Addition?
BlackJack

@Hanso: Also Numpy-Arrays kannst Du aus den beiden Objekten nicht (sinnvoll) erstellen, denn die liefern soweit man das am Quelltext sehen kann keine Zahlen sondern irgendwelche Objekte von denen man die Zahlen abfragt.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Hanso: das was Du da machst, ist wildes Herumraten, ohne Konzept. map liefert eine Liste, die Du aber gleich verwirfst. Außerdem versucht Du irgendwelche Values-Objekte zu addieren, von denen ich bisher nur weiß, dass sie ein dataDouble-Attribut haben. Wie ein +-Operator auf diesen Objekten definiert ist, weiß ich nicht. Was Du statt dessen willst, ist die U2-Listen in numpy-Arrays zu verwandeln und mit diesen zu rechnen.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Du musst vermutlich deine Objekte noch umwandeln. In etwa so:

Code: Alles auswählen

import numpy as np

vec1 = np.array([float(val) for val in OValues])
vec2 = np.array([float(val) for val in UValues])
print(vec1 + vec2)
float() muss möglicherweise durch eine geeignete Methode auf deinen Values ersetzt werden. Denn wie man an den Wert kommen könnte, hast du ja bisher nicht erwähnt und ich habe ehrlich gesagt gerade keine Lust, mich in die Schnittstelle des von dir verwendeten Packages einzuarbeiten.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Oder direkt ohne NumPy:

Code: Alles auswählen

zipped = zip(map(float, OValues), map(float, UValues))
print([o + u for o, u in zipped])
Oder die Variante ohne map(), was weniger umständlich ist, falls eine Methode bei den Value-Objekten aufgerufen werden muss:

Code: Alles auswählen

print([float(o) + float(u) for o, u in zip(OValues, UValues)])
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hanso hat geschrieben:Ich muss allerdings sagen dass das Programm lief, bevor ich den neuen Teil mit der Addition hinzugefügt habe. Auch jetzt läuft das Script einige Sekunden, gibt mir Daten aus - bis zu der Stelle mit der Addition. Abaqus gibt die Meldung "GUI detected error while waiting for ipc Connection to close. Abaqus/CAE Kernel exited with an error." aus.
Da sollte es doch wohl irgendwo ein Logfile geben oder eine Einstellung, dass man die tatsächliche Fehlermeldung sehen kann. Einfach mal recherchieren. Ohne vernünftige Fehleranzeigen ist so eine Umgebung zum Programmieren IMHO völlig unbrauchbar.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@snafu: sollte OValues tatsächlich ein Iterable mit Element sein, die in floats umgewandelt werden können, kann numpy daraus direkt ein Array machen:

Code: Alles auswählen

import numpy as np
vec1 = np.array(OValues, dtype=float)
vec2 = np.array(UValues, dtype=float)
print(vec1 + vec2)
BlackJack

@Sirius3: Ist aber eher unwahrscheinlich wenn man sich die Verwendung ansieht. Da haben die Elemente ja eine Methode die Floats liefert. Mehrzahl.
Hanso
User
Beiträge: 7
Registriert: Mittwoch 15. Februar 2017, 10:48

Danke für eure Hilfe erstmal. Ich habe das mit der Umwandlung probiert, allerdings hab ich die geeignete Methode noch nicht gefunden. float, int, Long funktionieren nicht. Die Fehlermeldung lautet:

TypeError: float()argument must be a string or a number, not 'FieldValue'

Allerdings konnte ich nicht herausfinden, wie ich die Umwandlung auf FieldValue anwenden kann
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Hanso: ja FieldValue haben noch eine Unterstruktur, aber die hast Du ja schon in eigenen Deinem Programm aufgelöst, denn sonst könntest Du ja numpy.savetxt nicht verwenden.

Code: Alles auswählen

def read_nodeset(odb, anz_frames, nodeset):
    result = []
    for i in range(1,anz_frames+1):
        values = odb.steps['Step-1'].frames[i].fieldOutputs['U'].getSubset(region=odb.rootAssembly.nodeSets[nodeset]).values
        result.extend(v.dataDouble[1] for v in values)
    return numpy.array(result)

ovalues = read_nodeset(odb, anz_frames, "VO")
uvalues = read_nodeset(odb, anz_frames, "VU")
summe = ovalues + uvalues
Ist dieses anz_frames überhaupt notwendig, oder könnte man auch direkt über odb.steps['Step-1'].frames iterieren?

Code: Alles auswählen

def read_nodeset(odb, nodeset):
    result = []
    for frame in odb.steps['Step-1'].frames:
        values = frame.fieldOutputs['U'].getSubset(region=odb.rootAssembly.nodeSets[nodeset]).values
        result.extend(v.dataDouble[1] for v in values)
    return numpy.array(result)

ovalues = read_nodeset(odb, "VO")
uvalues = read_nodeset(odb, "VU")
summe = ovalues + uvalues
Hanso
User
Beiträge: 7
Registriert: Mittwoch 15. Februar 2017, 10:48

@Sirius3: Danke, auf diese Weise funktioniert das Programm jetzt. Die einfachere Variante ohne anz_frames funktioniert ebenfalls. Jetzt kann ich mit dieser Struktur auch den Rest meines Programms vervollständigen. Ich danke vielmals allen die mir geholfen haben.
Antworten