ich habe folgendes Problem.
Im Anhang befindet sich die Beispieldatei, mit deren Daten ich folgenden Ablauf durchführen möchte.
Spalte 1 (t) ist die Zeit in Sekunden. Das System hat in unregelmäßigen Abständen Zeiten mehrfach aufgezeichnet.
Grundsätzlich sollen die Werte der Spalte 2 (Rf) < 90 sein. Die kompletten Zeilen, bei denen der Zellenwert > 90 beträgt, sollen eliminiert werden. Wenn folgende Bedingungen erfüllt werden:
-> Ist ein Zeitwert (t) mehrfach vorhanden?
JA: Überprüfe, ob in einem Bereich von t +- 3 Sekunden ein Rf < 90 zu finden ist.
wenn JA: lösche die komplette Zeile
wenn NEIN: beide Spalten (t und Rf) in neuer Variable speichern
Wie beschrieben möchte ich grundsätzlich pro Zeitwert einen Rf-Wert < 90 haben. Wenn einen Zeitwert aufgrund der beschriebenen Eliminierungen kein Rf-Wert mehr zugeordnet werden kann, dann kann die Toleranzgrenze der Zeit 9 Sekunden betragen.
Sollen Zeilen für Rf größer 90 nur eliminiert werden, wenn sich in dem Gebiet darum (idx-3:idx+3) keine Werte kleiner 90 befinden? Bedeutet eliminieren komplett entfernen oder auf NaN setzen?
In Zeile 7 taucht bei
t=5
der Rf-Wert 94 auf. Dieser soll gelöscht werden. Die anderen Zeilen mit
t=5
sollen erstmal bleiben (Und - zusätzlich - nach dem Filtern dann gemittelt zusammengefasst werden. Aber diesen Schritt am besten erstmal nicht berücksichtigen, sonst seh ich selbst nicht mehr durch ).
Zeile 16 hat bei Rf = 93 zwar kein doppeltes Sample (nur
t = 16
), aber im festgelegten Bereich (idx-3:idx+3) befinden sich Rf-Werte kleiner 90. Diese Zeile soll somit ebenfalls gelöscht werden. Das gleiche gilt für Zeile 19 (
t = 19
mit
Rf = 98
)
Zeile 10 und 11 erfüllen die Bedingung, dass die t-Werte nicht mehr als 9 Samples Abstand aufweisen.
Hintergrund ist, dass das Messsystem zwar erkannt hat, dass Werte über 90 unrealistisch sind und dann versuchte, gleiche Samples mit realistischen Werten zu belegen. Das klappte in vielen Fällen und deswegen würde ich gern erstmal die unrealistischen Peaks wegbekommen.
t = [123345555611:20]';
Rf = [43744686464994228688238671879313399864]';
%% Rf größer 90
offset = 3;
Rf = [NaN(offset,1); Rf; NaN(offset,1)]; % NaN nötig, falls range außerhalb des Vektors
t = [NaN(offset,1); t; NaN(offset,1)]; % auch hier, um Länge der Vektoren gleich zu halten
del_row = false(size(log_Rf));
sz = size(idx_Rf, 1);
n = NaN(sz, 2); % pre-allocate for ii = 1:sz
range = idx_Rf(ii) - offset:idx_Rf(ii) + offset;
ifany(Rf(range) <= 90)
del_row(idx_Rf(ii)) = true; % zu löschende Zeilen ermitteln else
n(ii, :) = [t(idx_Rf(ii)), Rf(idx_Rf(ii))];
end end
t(del_row) = []; % löschen
Rf(del_row) = [];
t = t(offset+1:end-offset); % NaN wieder entfernen
Rf = Rf(offset+1:end-offset);
M_neu = [t, Rf];
%% Wiederholungen in t
log_t = [false(1); diff(t) == 0]; % 1 für Wiederholungen, sont 0
start_idx_t = find(diff(log_t) == 1);
end_idx_t = find(diff(log_t) == -1);
for ii = 1:size(start_idx_t, 1)
range = start_idx_t(ii):end_idx_t(ii);
Rf(start_idx_t(ii)) = sum(Rf(range)) ./ length(range); % "Wiederholte" ersetzen end
M_neu kann man auch am Anfang erzeugen und dann damit weiterarbeiten anstatt mit t und Rf.
del_row braucht es nicht unbedingt, stattdessen log_Rf weiter verwenden und in else auf false setzen, statt in if auf true.
Die 9-Sample-Bedingung ist mir noch nicht ganz klar. Was soll zB geschehen, wenn zw. zwei t ein Abstand >9 vorliegt?
super ding!
Wie würde das dann aussehen, wenn M_neu schon anfangs erzeugt wird?
Ich stehe jetzt nämlich vor dem Problem, dass ich bis zum löschen der Zeilen mit Rf > 90 komme. Dann würde ich auf Grundlage von del_row gleich in der in der Hauptmatrix (16 Spalten) alles anwenden. Wenn ich das bei der Matrix (N) anwende, macht er aus einer 649x16 double eine 1x10374 double.
Bei Matrizen musst du Zeilen- und Spaltenindizes angeben.
kraudi13 hat Folgendes geschrieben:
Ich stehe jetzt nämlich vor dem Problem, dass ich bis zum löschen der Zeilen mit Rf > 90 komme. Dann würde ich auf Grundlage von del_row gleich in der in der Hauptmatrix (16 Spalten) alles anwenden. Wenn ich das bei der Matrix (N) anwende, macht er aus einer 649x16 double eine 1x10374 double.
also das ist erste Sahne Vielen Dank dafür. Das läuft so, wie ich es mir gedacht hab.
Bzgl. der 9-Sekunden-Regel. Das lässt sich in diesem Kontext nicht wirklich realisieren.
Wichtiger wäre mir noch ein weiteres Problem:
Ich würde gern einen bestimmten Bereich in der Matrix auswählen und als neue Matrix speichern.
In Spalte 1 stehen ja die Zeitsamples.
Der Bereich soll von vorn herein schon klar definiert sein. Zum Beispiel von 5 bis 15.
Nun möchte ich gern aus diesem Bereich ähnlich der folgenden Funktion das Maximum etc. berechnen.
Code:
startwert = M(5:,1); % aber für den Wert 5 bzw. den nächsthöheren vorhanden Wert, falls 5 nicht existiert
endwert = M(end-4,1); % für den Wert 15 (Ende abzüglich 4 Sekunden) bzw. den nächsthöheren vorhanden Wert, falls 15 nicht existiert. [y_max, x_max] = max(M(startwert:endwert,2));
startwert = find(M(:,1) == 5, 1, 'first');
endwert = find(M(:,1) == 15, 1, 'last');
[MX, I] = max(M(startwert:endwert,2)); % gibt Maximalwert und dessen Index zurück, nicht x und y, wie dein Code-Bsp. vermuten lässt
Dies lässt sich wie oben wieder mit (logischen) Vergleichsoperatoren und
find
lösen.
Wenn die Werte nicht zwingend vorhanden sind, könnte man quick & dirty die Suche nach Start-/Endwert in Schleifen gestalten. Die Schleife für den startwert bspw. von min_grenze bis max_grenze und für den endwert von max_grenze bis zum Maximal-/Endwert des Vektors.
Wenn die Werte nicht zwingend vorhanden sind, könnte man quick & dirty die Suche nach Start-/Endwert in Schleifen gestalten. Die Schleife für den startwert bspw. von min_grenze bis max_grenze und für den endwert von max_grenze bis zum Maximal-/Endwert des Vektors.
Ich hab das jetzt der einfach halt halber wie folgt gelöst und das funktioniert ganz ordentlich.
Wie die Meldung schon sagt, versuchst du auf Spalte 370 von M zuzugreifen, M hat aber nur 16 Spalten (und 848 Zeilen). Freundlicherweise nennt Matlab auch noch wo dieser Zugriff geschehen soll (Zeile 14).
Code:
??? Attempted to access end_idx_t(13); index out of bounds because
numel(end_idx_t)=12.
Error in ==> at 30
range = start_idx_t(ii):end_idx_t(ii);
ist es schon irgendjemandem gelungen, in dem Problem einen Fortschritt zu verzeichnen?
Ich bin immer noch ratlos.
Beste Grüße
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.