Datenreihen in Matlab einlesen und umsortieren
Mal neben den ganzen philosophischen Themen der letzen Zeit hier mal wieder was rein Technisches:
Datenreihen einzulesen in Matlab ist zwar nett und macht jeder, aber ich habe neulich zu einem kleinen Problem auf die Schnelle keine Lösung gefunden (weil man oft nur sehr theoretische Beispiele findet und die Matlab-Hilfe ausnahmsweise mal nicht gut verlinkt).
Das Problem war eine lange Liste mit Ergebnissen (bei mir mit Ansys mit etab und *vwrite erstellt) einzulesen und umzusortieren.
Und zwar eine mehrspaltige Tabelle mit vielen Zeilen, in jeder Zeile ein paar Ergebnisse zu einem Element. Aber die Elemente, sind in echt zweidimensional arrangiert. Und so hätte ich auch gern mein Array in Matlab und dann die Ergebnisse pro Element in die dritte Dimension nach hinten raus.
Also als Ausgang haben wir eine Datei “Beispiel.dat” mit folgendem Inhalt in ASCII:
elem no, stress Mises
1 13
2 14
3 15
4 17
5 20
6 21
7 22
8 25
9 27
10 30
11 33
12 35
Was ich jetzt wollte, war eine Matrix mit den Elementen 1,2,3 in der ersten horizontal Reihe bzw. 1, 4, 7, 10 in der ersten senkrechten Spalte und die Mises Spannungen “dahinter” als zweiten Layer.
Erstmal liest man die Datei in Matlab ein:
>> a = importdata(‘Beispiel.dat’) % reads the file
a =
data: [12x2 double]
textdata: {‘elem no, stress Mises’}
Wenn man nur Zahlen hat ist das einfacher, wenn man einen Header in der Datei hat, kann man die so voneinander trennen:
>> b = a.textdata{1,1} % the first line of text stuff
b =
elem no, stress Mises
>> c = a.data % all the numbers
c =
1 13
2 14
3 15
4 17
5 20
6 21
7 22
8 25
9 27
10 30
11 33
12 35
Jetzt das umsortieren der langen Liste in ein 3-dimensionales Array:
>> d = reshape(c,3,4,2) % shapes into a 3 rows, 4 columns, 2 layers
d(:,:,1) =
1 4 7 10
2 5 8 11
3 6 9 12
d(:,:,2) =
13 17 22 30
14 20 25 33
15 21 27 35
Und jetzt noch x und y vertauschen:
>> e = permute(d,[2 1 3]) % transforms / mirrors the rows and columns
e(:,:,1) =
1 2 3
4 5 6
7 8 9
10 11 12
e(:,:,2) =
13 14 15
17 20 21
22 25 27
30 33 35
Wenn man nur ein 2-dimensionales Array hätte, würde das durch Transponieren mit dem Hochkomma funktionieren z.B.:
>> e2 = d(:,:,1)’
e2 =
1 2 3
4 5 6
7 8 9
10 11 12
Befehle, die einem sonst noch so beim Umsortieren helfen könnten:
rot90
flipud
fliplr
squeeze
Und NaNs oder Nuller kann man mit Variationen hiervon rauswerfen (auch Zeilen voll NaNs, Leerzeilen oder so):
>> g = [-2 -1 0 1 2]
g =
-2 -1 0 1 2
>> h = isnan(0./g)
h =
0 0 1 0 0
>> j = ~h
j =
1 1 0 1 1
>> k = g(j)
k =
-2 -1 1 2
>> m = [-2 -1 0 NaN 2]
m =
-2 -1 0 NaN 2
>> n = isnan(m)
n =
0 0 0 1 0
>> p = ~n
p =
1 1 1 0 1
>> q = m(p)
q =
-2 -1 0 2
Das wärs auch schon was ich zu dem Thema sagen wollte. Und irgendwie fand ich das nicht alles auf einer Seite unter den ersten paar Suchergebnissen. Na, hoffentlich hilfts ja mal jemandem das schneller zu lösen dann.
Und wieviel Felder könne die Matrizen dann haben?
Für ein bisschen transponieren ist das schon viel Aufwand.
Wieviele Zahlen hast Du in einer Reihe?
Warum in diesem Programm?
Mann, gib mir ne Kolumne bei Euch und ich schreib den ganzen Scheiß, den ich bei der Diss gelernt hab hier rein. Das potenziert Eure Zugriffzahlen…
Och, so lang muss das natürlich nicht sein. Du kannst das natürlich auch auf nen Zweizeiler bringen (der Übersicht halber auf 2 Zeilen, geht bestimmt auch in einer):
a = importdata(’Beispiel.dat’);
e = permute(reshape(a.data,3,4,2),[2 1 3]); % reshapes everything
Aber das nützt dem verehrten Leser hier ja nicht so viel wenn er einen Schritt davon kapieren will.
Nuller rauswerfen geht natürlich auch als Einzeiler für nen Vektor:
g = [-2 -1 0 1 2] % only defines some values
k = g(~isnan(0./g)) % deletes all zeros
Meine Daten sind im Moment von einem 100×50 Pixel Bild für jeden Pixel 9 Werte einlesen. Wird vielleicht mal noch um nen Faktor 10 größer aber das wars auch schon.
Ich weiß nicht, bei wie vielen Feldern Schluß ist bei Matlab. Aber ich würde mal nicht mehr als 2GB auf einmal einlesen, dann hört die Speicherverwaltung bei nem 32bit Rechner auf ;-) Das wären dann ungefähr die Ergebnisse von 10000 x 10000 Pixel. Aber um 2Mrd Spannungswerte in einem FEM Programm auszurechnen würde dein Rechner vermutlich Jahrhunderte brauchen. Hihihi.
Matlab ist einfach handlich für Ingenieure. Deshalb dieses Programm.
In C oder C++ zum Beispiel hätte man dafür mindestens *ratterratter* na drei Schleifen, plus Speicher belegen plus lesen etc. naja, mindestens 8 Zeilen gebraucht.
Was hattest du denn und was für Zahlen und wie viele hast du damit verwurstet zu welchem Zweck?