Numpy Array umsortieren

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Kniffte
User
Beiträge: 64
Registriert: Dienstag 27. September 2016, 11:05

Hallo Zusammen,

Folgende Ausgangsituation:
Ich habe einen Numpy-Array erzeugt aus meinen Eingaebdaten, der folgende Form hat:

Numpy gibt mir als input_array.shape ==> (3,) aus

Code: Alles auswählen

[[ '1.1', '2.2', '3.3', '8.1', '9.2', '7.3' ]
 [ '1.1', '2.2', '3.3', '8.1', '9.2', '7.3' ]
 [ '1.1', '2.2', '3.3' ]]
Nun möchte ich diesen gerne umsortieren in ein input_array.shape ==> (5, 3).
Also sollte es dann wie folgt aussehen:

Code: Alles auswählen

[[ '1.1', '2.2', '3.3' ]
 [ '8.1', '9.2', '7.3' ]
 [ '1.1', '2.2', '3.3' ]
 [ '8.1', '9.2', '7.3' ]
 [ '1.1', '2.2', '3.3' ]]
Ich habe dies mit input_array.resize(5, 3), aber damit erhalte ich nicht das gewünschte Ergebnis.

Wäre für Hilfe dankbar?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Kniffte: welchen Typ hat denn nun Dein input_array? Für mich sieht das so aus, als ob es 3 Listen enthält. Dann solltest Du zuerst per hstack daraus ein Array mit Strings machen und kannst danach mit reshape die Form ändern:

Code: Alles auswählen

>>> input_array
array([['1.1', '2.2', '3.3', '8.1', '9.2', '7.3'],
       ['1.1', '2.2', '3.3', '8.1', '9.2', '7.3'], ['1.1', '2.2', '3.3']], dtype=object)
>>> numpy.hstack(input_array).reshape((5,3))
array([['1.1', '2.2', '3.3'],
       ['8.1', '9.2', '7.3'],
       ['1.1', '2.2', '3.3'],
       ['8.1', '9.2', '7.3'],
       ['1.1', '2.2', '3.3']], 
      dtype='<U3')
BlackJack

@Kniffte: Eventuell sollte man auch einen Schritt früher ansetzen und erst einmal klären wie Du zu einem Array mit Listen kommst, die Zeichenketten enthalten die vom Inhalt aber alle wie Zahlen aussehen. Willst Du am Ende wirklich ein Array mit Zeichenketten?
Kniffte
User
Beiträge: 64
Registriert: Dienstag 27. September 2016, 11:05

Hallo Sirius & BlackJack,

Am Ende möchte ich gern einen Array mit Floats in der Form (5, 3).

Ich fang mal ganz am Anfang an:
Ich habe eine Textdatei, deren Zeilen ich in Elemente einer Liste einlese.
Danach prüfe ich jede Zeile auf reguläre Ausdrücke und "bereinige" die Listenelemente.
Danach suche ich Anfang und Ende der Zahlenbereiche.
Schneide mir die Datenbreiche aus und weise sie neuen Variablen zu. Diese sind dann Listen im folgenden Format:

Code: Alles auswählen

[ '1.1, 2.2, 3.3, 8.1, 9.2, 7.3', '1.1, 2.2, 3.3, 8.1, 9.2, 7.3', '1.1, 2.2, 3.3' ]
Die Listenelemente wandle ich dann wieder in Einzellisten mittels split()-Befehl um und erhalte das oben angegebene Format:

Code: Alles auswählen

[[ '1.1', '2.2', '3.3', '8.1', '9.2', '7.3' ],
 [ '1.1', '2.2', '3.3', '8.1', '9.2', '7.3' ],
 [ '1.1', '2.2', '3.3' ]]
Diese Liste lese ich dann in einen numpy.array() ein, den ich dann umsortieren möchte.

ich hoffe, dass ich mich einigermaßen verständlich ausgedrückt habe?
Sollte ich viell schon früher mit dem numpy.array() ansetzen?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Kniffte: vielleicht hilft Dir ja schon genfromtxt weiter. Wenn nicht, hilft uns, genau zu wissen, was denn da bereinigt wird.
Auf jeden Fall wandelst Du Deine Daten viel zu früh in ein numpy-Array um. Gehen wir von einer Liste mit Strings aus:

Code: Alles auswählen

import numpy
from itertools import chain
input_data = [ '1.1, 2.2, 3.3, 8.1, 9.2, 7.3', '1.1, 2.2, 3.3, 8.1, 9.2, 7.3', '1.1, 2.2, 3.3' ]
input_values = chain.from_iterable(line.split(',') for line in input_data)
data = numpy.fromiter(input_values, dtype=float)
data = data.reshape((5,3))
Kniffte
User
Beiträge: 64
Registriert: Dienstag 27. September 2016, 11:05

@Sirius3:
genfromtxt habe ich mir mal angeschaut, aber ich denke, dass meine Textdatei dafür zu "unstrukturiert" ist.
Ich muss am Anfang und Ende was wegschneiden, zwischen den Datenbereichen Kommentare entfernen.
Jede Zeilennummer entfernen, die manchmal mit und manchmal ohne Komma getrennt steht...usw.
Aber ich habe in der Numpy-Doku hab ich auf der folgende Seite numpy.fromregex() gefunden. Was viell auch funktionieren könnte...

Dein Codevorschlag funktioniert soweit sehr gut bzw. führt mich zum gewünschten Ergebnis. Danke! :)

Nun möchte ich noch gern meinen Denkfehler verstehen:
Kannst du mir viell erklären, was chain.from_iterable() genau macht?
Also du übergibst dort die Daten, so wie ich sie im zweiten Schritt umgewandelt hatte als:

Code: Alles auswählen

[[ '1.1', '2.2', '3.3', '8.1', '9.2', '7.3' ],
 [ '1.1', '2.2', '3.3', '8.1', '9.2', '7.3' ],
 [ '1.1', '2.2', '3.3' ]]
...ausgegeben wird ein Objekt...was genau ist hier mit den Daten passiert? (es scheint ja wieder ein iterable zu sein!?)
Dann wird dieses Objekt an numpy.fromiter() übergeben, wobei die Elemente In floats umgewandelt und dann als Numpy.array ausgegeben werden. Und dann kann man den Array umformen.
Kniffte
User
Beiträge: 64
Registriert: Dienstag 27. September 2016, 11:05

Hallo,

Ich hätte noch zusätzliche Fragen:

1) Kann ich auch die Elemente der Liste in der oben genannten Form mittels list comprehension in floats umwandeln und dann direkt einen numpy.array daraus erzeugen?

Code: Alles auswählen

data = [[ '1.1', '2.2', '3.3', '8.1', '9.2', '7.3' ],
 [ '1.1', '2.2', '3.3', '8.1', '9.2', '7.3' ],
 [ '1.1', '2.2', '3.3' ]]
data = [float(x) for subdata in data for x in subdata]
data_array = numpy.array(data)
2) Gibt es eine Möglichkeit bei Array.reshape() die Angabe der Zeilen wegzulassen und nur die Anzahl der Spalten vorzugeben?
Wenn ich z.b. vorher nicht weiß wieviele Zeilen sich aus den Daten ergeben (nur die Spaltenanzahl ist immer fest mit 3 festgelegt).

3) Nach der Umwandlung in den numpy-Array erhalte ich bei 2 von 4 Datensätzen die Elemente als Fließkommazahlen mit Exponentangabe (z.b. 0.125485e+01) und bei den anderen beiden nur die normale Darstellung der Fließkommazahl. (z.b. 1.25485). Woran könnte das liegen?
Die Eingabedaten haben immer die gleiche Form. (Fließkommazahl mit 5 Nachkommsstellen -> z.b. 1.25485 oder -0.01256 ...)
BlackJack

@Kniffte: 1) Kann man machen, aber *warum*? So wird erst eine Liste erstellt und die dann Elemente dann noch mal konvertiert/in ein Array umkopiert.

2) Die Dokumentation sagt ja, gibt es. :-)

3) Wie die Zahlen dargestellt werden kann zum Beispiel daran liegen wie gross/klein die Werte sind. Wie die bei der Eingabe mal ausgesehen haben, wird nirgends gespeichert. Und wie die bei der Ausgabe aussehen musst Du für die Ausgabe festlegen. Das was Du da siehst ist ja nur eine Darstellung für Dich als Programmierer. Wenn das Array zu gross wird, dann wird auch nicht mehr alles angezeigt, weil Dir das als menschlicher Leser in der Form eh nichts nützen würde.
Kniffte
User
Beiträge: 64
Registriert: Dienstag 27. September 2016, 11:05

@BlackJack
BlackJack hat geschrieben:2) Die Dokumentation sagt ja, gibt es. :-)
Hab´s jetzt auch gefunden. ==> numpy.reshape(-1, 3) :-)

Danke
Antworten