ich suche nach einem möglichst effizienten Lösungsweg für folgendes Problem. Angenommen ich habe Daten in einem 2x2 struct gespeichert, wobei jedes Feld eine Matrix enthält. Alle Matrizen haben dieselbe Spaltenanzahl (die Dimension der Daten ist also gleich), können aber unterschiedliche Zeilenanzahlen enthalten (jede Matrix repräsentiert eine 'session'. Die Anzahl der gewonnenen Daten aus diesen kann also unterschiedlich sein)
Nun will ich künstlich einen festgelegten Prozentsatz fehlender Daten einführen. Ein fehlendes Datum ist in allen Sätzen durch einen bestimmten Eintrag gekennzeichnet, z.B. -999. Alle Datensätze enthalten von Haus aus schon einen gewissen Prozentsatz fehlender Daten, den es dann auf den gewünschten Prozentsatz aufzustocken gilt. Und die Umsetzung ist irgendwie problematisch.
Ideal wäre es, wenn man irgendwie Referenzen auf Matrixdaten erzeugen könnte. Dann müsste ich nur berechnen, wieviele Datensätze insgesamt ungültig sein müssen, um den gegebenen Prozentsatz zu erreichen, kann die gültigen Einträge aller vier Matrizen aneinanderhängen und per Referenz einfach ein paar Einträge abändern.
Ohne Referenzen hab ich dann Probleme bei der Indizierung, denn den Prozentsatz global über alle Matrizen zu berechnen, diese aber getrennt zu indizieren, scheint mir sonst nicht möglich oder komplizierte Rumrechnerei mit den Indizes zu sein.
Es ist immer schwierig eine Text-Beschreibung einer komplexeren Matlab-Datenstruktur zu verstehen. Das Posten von Matlab-Code wäre da wohl hilfreicher.
Die Benutzuing von "magischen Zahlen" wie -999 ist immer ein schlechter Ansatz. Wenn es sich nicht mit NaN oder Inf lösen lässt, wäre es besser eine 0 zu nehmen und die Information über die Nicht-Validität in einem Logischen Array zu speichern. Es gibt in der Geschichte der Programmierung einfach zu viele Fälle, in denen die angeblich niemals auftredene Zahl plötzlich durch eine Erweiterung des Programms doch zu einem möglichen wurde. So waren auf den alten 8-Bit-Basic-Rechnern Endlos-Schleifen niedlich per "FOR i = 1 TO 4e4" zu implementieren, sprich "four e four" oder "forever". Da BASIC bei 32767 einen Überlauf erzeugte, fing dort die Schleife wieder bei 1 an. Natürlich war dies ein grober Bug auf 16-Bit-Rechnern und großen Mengen an Code mussten neu geschrieben werden.
Ich habe nicht verstanden, was eine "Referenz auf Matrixdaten" sein soll.
Wenn ich Dich richtig verstehe, hast Du etwas wie:
Nun möchtest Du irgendwelche der Matrix-Elemente durch einen speziellen Wert ersetzen. Nun kannst Du einen Vektor der Länge3+12+8+17 erstellen und darin den Index des dazugehörigen Structs speichern. Dabei ist es noch hilfreich, den linearen Index zu verwenden: "S(2,2)" ist das gleiche wie "S(4)", falls "S" zwei Zeilen besitzt.
Die Benutzuing von "magischen Zahlen" wie -999 ist immer ein schlechter Ansatz.
Ist mir als Informatiker bekannt, aber der Datensatz ist nicht von mir selbst und soll wohl auch unabhängig von der Programmiersprache sein (deshalb kein NaN ?!). Ich könnte das Ganze im Nachhinein in was Sinnvolleres umwandeln, komme aber trotzdem nicht umhin, nach diese magic numbers zu suchen.
Jan S hat Folgendes geschrieben:
Ich habe nicht verstanden, was eine "Referenz auf Matrixdaten" sein soll.
Damit meinte ich sowas wie Zeiger in C++. Ich erzeuge mir einen Zeiger auf eine Matrix, mit dem ich machen kann, was ich will und über einen speziellen Zugriff auch die Daten ändern kann, auf die er zeigt.
Ich glaube aber, mit deinem Beispiel müsste ich es hinkriegen.
bei der finalen Indizierung fahr ich irgendwie gegen die Wand und der Code sieht auch alles andere als toll aus. Ich versuch mal zu beschreiben, was ich gemacht hab:
Code:
% eva.dset bildet meinen gesamten Datenbestand, dessen Gesamtlänge ich hier erst mal ermittele
evaLen = size(eva.dset{1}, 1) + size(eva.dset{2}, 1);
% missingDataPct ist ein Parameter und der Prozentsatz "fehlerhafter" Datensätze, also solchen, denen Werte fehlen. Ich zähle also, wieviele Datensätze am Ende "dirty" sein müssen, damit ich den gewünschten Prozentsatz erreiche
missingDataCnt = round(evaLen * missingDataPct / 100);
% Anschließend filtere ich mir alle "sauberen" Datensätze raus (cols selektiert die Features eines Datensatzes, die mich interessieren) ...
mask1 = eva.dset{1}(:, cols) == -999;
mask2 = eva.dset{2}(:, cols) == -999;
mask1 = any(mask1');
mask2 = any(mask2');
wolvesMasked = eva.dset{1}(~mask1, cols);
sheepsMasked = eva.dset{2}(~mask2, cols);
% ...und kann zählen, wieviele dirty records mein Datenbestand von Haus aus enthält. Die Anzahl dieser muss ich von der Anzahl der noch zu verfälschenden Datensätze abziehen, damit ich am Ende genau den richtigen Prozentsatz erreiche
inherentlyMissing = length(find(mask1)) + length(find(mask2));
missingDataCnt = missingDataCnt - inherentlyMissing;
Und wie mache ich dann hier weiter? Wahrscheinlich bin ich gar nicht so weit weg von einer Lösung, aber es ist ein endloses Index-Hinundhergeschiebe und wirklich nicht mehr schön. Ich habe mit wolves/sheepsMasked ja genau alle sauberen Datensätze und eine genaue Anzahl (missingDataCnt) der Sätze, die ich noch verfälschen muss.
Am Ende muss ich ja sowas schreiben wie: eva.dset{cellIndex}(rowIndex, colIndex) = -999;
colIndex ist total simpel, weil einfach gleichverteilt zufällig eines der Features auswähle, das ich löschen will.
Den cellIndex kriege ich mit deiner Methode von oben auch leicht raus. Ich erstelle mir so einen SIndex-Vektor, der eine 1 für jeden sauberen Datensatz in Zelle 1 und eine 2 für jeden sauberen Datensatz in Zelle 2 enthält. Dann ziehe ich einfach zufällig ein paar Indizes aus diesem Vektor - also auch kein Problem.
Richtig schwer wird es nur beim rowIndex. Wie komme ich an den ran?
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.