Verfasst am: 02.07.2015, 17:22
Titel: Berechnungskriterium bei unzureichender Länge eines Arrays
Hallo zusammen!
Ich möchte ein universelles Berechnungskriterium für die korrekte Auswertung von Daten definieren. Das folgende Skript liest Messwerte (2 s Intervall) aus Dateien aus und es sollen 10 min Mittelwerte gebildet werden. Es werden täglich Messungen gemacht. Bei der Auslesung sind es dann nicht mehr 43200 Werte, sondern eben etwas weniger. Die Berechnung der Mittelwerte funktioniert, bis zum Tag der Auslesung. Dann kommt das Problem, dass der letzte Mittelwert (bei beispielsweise 43131 Messungen) nicht mehr berechnet werden kann (Matlab überschreibt diesen Wert in Ergebnissemit dem darüberliegenden (dem Mittelwert vom Vortag zu diesem Zeitpunkt)
Was noch wichtig ist, alle Mittelwerte müssen später zu einem Array zusammengefügt werden.
Ich denke dass mein Ansatz schon etwas unglücklich ist, da die Mittelwerte nur nach erfolgreicher Berechnung in die Matrix Ergebnisse geschrieben werden können. Sie sollten vielleicht gleich in einem Array untergebracht werden.
Code:
clc % ----- Mittelwerte aus 10 min bilden (30 Werte pro Min, % 30*10 = 300 Werte/ 10 min))
delta_t = 300;
%Erstellen einer Liste mit .csv Endung
list = dir('*.csv');
names = {list.name};
Mittelwert = zeros(1,43200/300);
Ergebnis = zeros(length(names),43200/300);
tic for i = 1:length(names)
t = 1;
disp(names{i}) % Erstes Element
fid=fopen(names{i});
format='%*s %*s %s %*s %*s %*s %*s %*s %*s';
data=textscan(fid,format,'headerLines',3,'Delimiter',';');
%Cell zu Array
Array = data{1};
% Ersetzen der Kommata durch Punkte
Array=regexprep(Array, ',', '.');
%Strings zu Double aendern
Array=str2double(Array);
for j = 1:(length(Array))/300
Mittelwert(j) = mean(Array(t:t+delta_t-1));
t = t + delta_t;
end
Ergebnis(i,:) = Mittelwert;
fclose(fid);
disp(i) end toc
Ich habe auch schon überlegt, die mod Function (Rest) zu verwenden aber iwie klappt es nicht so recht. Sicherlich muss dort eine While Schleife rein, sodass eben bei der 'Auslesedatei' anders verfahren wird. Habt ihr vllt. ein paar Vorschläge? Ich wäre wirklich sehr dankbar!
kannst du einen beispiel datensatz zur verfügung stellen und erleutern was nicht so ist wie du dir das vorstellst?
Zitat:
Ich habe auch schon überlegt, die mod Function (Rest) zu verwenden aber iwie klappt es nicht so recht.
das ist iwie schade.. leider kann ich zu iwie klappt das nicht iwie keinen lösungsvorschlag machen bitte genauer ausführen. was soll denn als ergensiss rauskommen wenn es halt nur 43131 werte sind?
_________________
Beim Anhängen wird mir Die Erweiterung csv ist hier verboten angezeigt? Sonst gib mir doch deine E-Mail adresse dann kann ich dir mehrere Dateien schicken
Die dritte Spalte wird ausgelesen (Wind 1/m/s). Als Ergebnis möchte ich bei bsp. 43131 Werten 143 Mittelwerte haben. Es sind auch Dateien dabei, die ca 31000 Werte haben. Als Ergenis sollen in c_m so viele 10 min Mittelwerte wie möglich abgelegt werden! Da dies eben nicht immer geht, muss, wenn ein Rest bleibt, dieser rausgenommen werden. Aktuelles Problem: In Array wird jeder zweite Wert mit NaN belegt, woran liegt das? Mein Code sieht nun so aus:
Code:
clearall % ----- Mittelwerte aus 10 min bilden (30 Werte pro Min, 30*10 = 300 Werte/10 min))
delta_t = 300;
%Erstellen einer Liste mit .csv Endung aus gewähltem Verzeichnis
list = dir('*.csv');
names = {list.name};
c_m = []; % Erstellen eines leeren Vekors ( Ablegen der Ergebnisse)
Mittelwert = zeros(1,43200/300);
tic for i = 1:length(names)% Berechnung für jede Datei i
t = 1;
disp(names{i})% Anzeigen der ladenden Dateu
fid=fopen(names{i}); % Öffnen der Datei i format='%*s %*s %s %*s %*s %*s %*s %*s %*s'; % Format=Lies die 3. Spalte (%s) % Auslesen, ab Zeile 3 (headerlines,'3') mit ; als Trennzeichen
data=textscan(fid,format,'headerLines',3,'Delimiter',';');
Array = data{1}; % Cell zu Array
Array=regexprep(Array, ',', '.'); % Ersetzen der Kommata durch Punkte
Array=str2double(Array); % Strings zu Double aendern
k = length(Array); % k als Kriterium bei 143 Mittelwerte
for j = 1:round((length(Array))/300) %Bilde Mittelwerte von 1 bis 144
k = k - 300;
if k < 0% Sonderfall bei Auslesung < 10 min, k wird kleiner 0
Mittelwert = Mittelwert(1:143); % --->Anzahl der Mittelwerte soll variabel werden! else
Mittelwert(j) = mean(Array(t:t+delta_t-1));
t = t + delta_t; % Laufvariable zur Mittelwertbildung end end
c_m = [c_m Mittelwert]; % Mittelwert nach Berechnung j in cm ablegen
In Array wird jeder zweite Wert mit NaN belegt, woran liegt das? Mein Code sieht nun so aus:
das liegt daran das sich das format deiner daten ab 15041000 ändert. in der csv datei kommen 2 weitere spalten dazu. da spasst nicht mehr zu deinem format string.
zu deinem anderen problem
ich würde den mittelwert so berechnen.
und noch ne anmerkung. j und i sind die imaginären einheiten. ich würde sie nicht als laufindex verwenden. außerdem ist clear all mist. das löscht alle daten was dazu führt das man sie wieder nachladen muss und es löscht, was noch viel schlimmer ist, die debug marken. warum bei dir nans vorkommen lässt sich leicht rausfinden wenn man den debugger benutzt und guckt was passiert. das geht natürlich nicht wenn man clear all benutzt.
_________________
mit der Zeile lässt sich auch die for schleifen umgehen, was alles schneller macht, genial! Die Bezeichnung für den Laufindex habe ich geändert, und auch das clear all rausgenommen, danke für den Hinweis! (Ich bin eben kein Programmierer )
Da ich alle c_m in einem Array brauche habe ich nun folgendes gemacht:
Klappt auch (bis auf die Formatierungssache aber das ist erstmal Nebensache).MATLAB sagt mir, das es dadurch etwas länger braucht, was wohl etwas mit der Speichervorbelegung zu tun hat. Da ich auch von sowas keine Ahnung habe, wollte ich fragen, ob es auch eleganter geht, die einzelnen c_m nacheinander in einem Array unterzubringen.
.MATLAB sagt mir, das es dadurch etwas länger braucht, was wohl etwas mit der Speichervorbelegung zu tun hat. Da ich auch von sowas keine Ahnung habe, wollte ich fragen, ob es auch eleganter geht, die einzelnen c_m nacheinander in einem Array unterzubringen.
das liegt daran das das bei jedem schleifen durchlauf sich die größe der variablen ändert. das kann bei großen datenmengen schonmal ne menge zeit fressen.. bei deinem beispiel hällt sich das aber in grenzen. es gibt einige ansätze wie man mit unbekannten datenmengen umgeht. wenn du weist wie groß die daten maximal werden können kannst du das als grenze nehmen und den speicher sconmal reservieren und dann später das löschen was nicht gebraucht wurde. oder du kannst den speicher in blöcken anlegen. wenn er voll ist neuer block dazu etc.
du kannst zb sagen das ja deine tage immer maximal 144 haben manchmal 143 einträge als kannst du anzahl der files mal 144 elemente als nan reservieren und dann halt da drinn die werte speichern. und am ende die nan löschen die übrig geblieben sind.
_________________
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.