array in Zeile ausgeben

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Benutzeravatar
UlliD
User
Beiträge: 4
Registriert: Freitag 21. September 2018, 09:38

Grüß euch, ich platze gleich mit einer konkreten Frage zu euch. Kurzer background: ich bin beruflich mit einem python-script konfrontiert, das ich ein bisschen umbauen muss. Ich "spreche" Fortran, kann den Code daher natürlich lesen, aber mir ist die Syntax von Formatierungen nicht ganz klar. Ich habe - es handelt sich um ein berufliches Problem - auch nicht die Zeit, mich komplett zu vertiefen. Habe mehrere Stunden damit verbracht, selbst herauszufinden, was ich suche, bin aber gescheitert. (Aber immerhin bei euch gelandet!)

Folgendes Problem: Ich möchte in einer Zeile in einer Datei folgende Ausgabe machen, d.h. es soll folgendes stehen:
"Spalte_A" "Spalte_B" "Inhalt eines arrays als Zeile" #dieses Array mit float als Inhalt hat immer eine andere Länge
ich probiere also:

import csv ## zum Exportieren von Daten
import numpy as np ## mathematische Funktionen
out = open('MS.csv', 'wb')
myout = csv.writer(out, delimiter= ",")
line = np.transpose(timeSteps) ##hier probiere ich, das array zu transponieren
row = zip('Spalte_A', 'Spalte_B', line)
myout.writerow(row)

Mein Resultat ist aber nicht so, wie ich mir das vorstelle ... denn es schreibt mir nicht die Worte "Spalte_A", dann "Spalte_B" und dann das array als Zeile, sondern
"('S', 'S', 0.0)","('p', 'p', 11.101343724457138)","('a', 'a', 2628003.2485391521)","('l', lt', 5256000.9192750929)", usw.

Wie kann ich das array timeSteps als Zeile ausgeben, nach den beiden Spaltenbezeichnungen?

Ulli
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@UlliD: Also mir ist das gwünschte Ausgabeformat noch nicht ganz klar. Du hast ein 2D-Array das eine Spalte enthält, sagen wir mal so was?

Code: Alles auswählen

In [14]: np.array([[i] for i in range(10)])
Out[14]: 
array([[0],
       [1],
       [2],
       [3],
       [4],
       [5],
       [6],
       [7],
       [8],
       [9]])
Und willst am Ende so etwas als Zeile in der Ausgabedatei haben (ich habe die beiden ersten Werte mal nur mit drei Buchstaben angegeben)?

Code: Alles auswählen

abc,xyz,0,1,2,3,4,5,6,7,8,9
Dann ist das Transpose schon mal ein richtiger Schritt, reicht aber nicht ganz weil es ja immer noch 2D ist. Du müsstest noch die eine Zeile da raus holen. Und zum Beispiel in eine Liste umwandeln, denn die ersten beiden Werte müssen ja davor kommen und da würde es sich anbieten die in einer Liste zu speichern die dann um die Werte aus dem Array erweitert werden.

Code: Alles auswählen

In [15]: xs = _

In [16]: xs.T
Out[16]: array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])

In [17]: xs.T[0]
Out[17]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [18]: list(xs.T[0])
Out[18]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [19]: ['abc', 'xyz'] + list(xs.T[0])
Out[19]: ['abc', 'xyz', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
`zip()` ist hier falsch, das nimmt immer die jeweils ”zusammengehörenden” Elemente aus den übergebenen iterierbaren Werten und fasst die zu Tupeln zusammen und hört zudem auf sobald das erste iterierbare Argument nichts mehr liefert:

Code: Alles auswählen

In [20]: list(zip('abc', 'xyz', xs.T[0]))
Out[20]: [('a', 'x', 0), ('b', 'y', 1), ('c', 'z', 2)]
Hier sieht man schon im ersten Tupel das 'a' vom ersten Argument, das 'x' vom Zweiten, und die 0 vom Dritten, und so weiter.

Und in dem Beitrag siehst Du auch eine der stärken von Python: Man kann solche Sachen interaktiv in einer Python-Shell ausprobieren und sich leicht die Zwischenergebnisse anschauen. Das ist ein sehr nützliches Werkzeug beim Lernen, aber auch später noch beim Entwickeln von Ausdrücken oder bei der Fehlersuche.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
UlliD
User
Beiträge: 4
Registriert: Freitag 21. September 2018, 09:38

@_blackjack_ danke, du hast mir sehr geholfen! Die list-Funktion hat mir gefehlt. Ich habe jetzt genau die Überschrift, die ich will.

Ich habe jetzt also

line = np.transpose(timeSteps)
myout.writerow(['abc', 'xyz'] + list(line))

und es funktioniert genau richtig. :-)
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@UlliD: Aber wie sieht denn dann `timeSteps` aus das `transpose()` irgend etwas sinnvolles verändert? Ich kann mir da gerade nichts vorstellen was nicht dazu führt das man am Ende Zeichenkettenrepräsentationen von Numpy-Arrays in der Datei hat. Etwas was sicher nicht gewollt ist.

Code: Alles auswählen

In [29]: [] + list(xs)
Out[29]: 
[array([0]),
 array([1]),
 array([2]),
 array([3]),
 array([4]),
 array([5]),
 array([6]),
 array([7]),
 array([8]),
 array([9])]

In [30]: [] + list(xs.T)
Out[30]: [array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])]
Nur wenn das Array eindimensional ist, bekommt man ”nackte” Zahlen, aber bei einem solchen Array ist transponieren eine Nulloperation:

Code: Alles auswählen

In [31]: xs.ravel()
Out[31]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [32]: xs.ravel().T
Out[32]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
UlliD
User
Beiträge: 4
Registriert: Freitag 21. September 2018, 09:38

Ja, du hast völlig recht. Es geht ohne diese Zeile genauso.

Ich hänge noch eine weitere Formatierungsfrage dran. Denn unterhalb meiner Überschriftenzeile (die wir gerade aus n=Anzahl der timeSteps gemacht haben), stehen in der Datei dann die Werte aus

array1(m), array2(m), array3(m x n)

Ich hatte das auch mit zip gemacht, und zwar so:

rows = zip(array1, array2, list(array3)) #In diesem Fall WILL ich die Tupel, die Anzahl der Werte passt auch zusammen
myout.writerows(rows)

Mein Output schaut jetzt so aus:

382659,0.0,"(847.11495, 847.11495, 847.11495, 847.11495, ....
382603,56.0,"(847.81922, 847.81922, 847.81922, 847.81922, ...
...

Was mich stört, ist das "( am Anfang der Liste, anstatt eines Beistriches. Wie bekomme ich hier eine Zeile analog zur Überschrift? Muss ich hier über eine for-Schleife gehen?
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@UlliD: Du willst die Tupel nicht direkt, denn die haben ja immer drei Elemente: den jeweiligen Einzelwert aus `array1` und `array2` und Liste von Zahlen die als *ein* Element als Zeichenkette geschrieben werden. Wobei mich da jetzt die runden Klammern etwas wundern, denn bei `list()` hätte ich eckige Klammern erwartet. Man kann da jetzt Zeile für Zeile das machen was Du auch für die erste Zeile gemacht hast, aber ich glaube ich würde da eher ein neues Array aus den dreien erstellen und das dann an `writerows()` übergeben. Schau Dir mal `numpy.hstack()` & Co an.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
UlliD
User
Beiträge: 4
Registriert: Freitag 21. September 2018, 09:38

Danke nochmals, jetzt habe ich (vorerst) keine Frage mehr, Problem gelöst!
Antworten