how to delete nan values from array columns without losing data from other columns
4 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
dareen
am 11 Mai 2024
Kommentiert: Mathieu NOE
am 14 Mai 2024
i have a huge file from a lab expremient
every run gives me 4 columns and every 2 out of the 4 start with nan then 2 nan vars and end with nan and 3 nan vars i want to delet the nan values without losing any data so that when i try to make graphs from it every graph will have enough inputs and neither of them get lost
i am espisally troubled by the second 2 columns of every 4 and how to deal with them
11 Kommentare
Mathieu NOE
am 14 Mai 2024
glad I could help a bit , but this was just a starter
ok, let's focus on the selected runs (for both files I presume ?)
these 2 lines are indeed just to extract a block of 4 contiguous columns , and we simply shift by a factor 4 when we change to the next run :
ind_cols = (1:4)+(ck-1)*4;
data_this_run = data(:,ind_cols);
and yes this line is not anymore of any use (I used it for another purpose that I removed afterwards) : [m,n] = size(data_this_run);
I'll come back soon with a new code
Akzeptierte Antwort
Mathieu NOE
am 14 Mai 2024
ok, so this is now the main dishes....
have first tried this code on the first data file , will adapt to your new files as soon as possible
have fun !
data= readmatrix('expr2lab.csv'); % or readtable or whatever
runs = [12 , 16 ,17,20,22,24,29,30,31,34,33,11]; % selection of best runs
%% main loop
for ck = 1:numel(runs)
k = runs(ck);
ind_cols = (1:4)+(k-1)*4; % Time (s) Position (m) Velocity (m/s) Acceleration (m/s²)
data_this_run = data(:,ind_cols);
[m,n] = size(data_this_run);
Time = data_this_run(:,1);
Position = data_this_run(:,2);
Velocity = data_this_run(:,3);
Acceleration = data_this_run(:,4);
%% fit on acceleration data
% remove all NaN's first
ind = isnan(Time) | isnan(Acceleration);
Time(ind) = [];
Position(ind) = [];
Velocity(ind) = [];
Acceleration(ind) = [];
% select valid data between first max peak and end of data
[v,indm] = max(Acceleration); % search for the first positive max peak
nn = numel(Time);
[b,yf] = exp_decay_sinus_fit(Time(indm:nn),Acceleration(indm:nn));
% b array contains 5 coefficients according to this equation (model)
% y = b(1).*exp(b(2).*x).*(sin(2*pi*b(3)*x + b(4))) + b(5)
eq_str = [ ' y = ' num2str(b(1),'%.2f'),'* exp(-' num2str(-b(2),'%.2f') ' t * sin(2*pi*' num2str(b(3),'%.2f') ' t + ' num2str(b(4),'%.2f') ' ) + (' num2str(b(5),'%.2f') ')'];
figure(ck)
subplot(3,1,1),plot(Time,Position)
title(['Run # : ' num2str(k)]);
ylabel('Position');
subplot(3,1,2),plot(Time,Velocity)
ylabel('Velocity');
subplot(3,1,3),plot(Time,Acceleration,Time(indm:nn),yf);
ylabel('Acceleration');
legend('data',eq_str);
end
%%%%%%%%%%%%%%% functions %%%%%%%%%%%%%%%%%%%%%%
function [B,yf] = exp_decay_sinus_fit(t,y)
[yu,indm] = max(y);
yl = min(y);
yr = (yu-yl); % Range of y
yz = y-yu+(yr/2);
% zero crossing are performed on first 1/3 of data (better signal to
% noise ratio)
n = round(numel(y)/3);
yz = yz(indm:n); % extract from first major peak to end of 30% of data
zt = t(yz(:) .* circshift(yz(:),[1 0]) <= 0); % Find zero-crossings
per = 2*mean(diff(zt)); % Estimate period
freq = 1/per; % Estimate frequency
% initial phase estimate
tmax = t(indm);
phase_init = mod(-2*pi*freq*tmax + pi/2,2*pi); % initial phase estimate
ym = mean(y); % Estimate DC value (offset)
fit = @(b,x) b(1).*exp(b(2).*x).*(sin(2*pi*b(3)*x + b(4))) + b(5); % Objective Function to fit
fcn = @(b) norm(fit(b,t) - y); % Least-Squares cost function
B = fminsearch(fcn, [yr; -0.1; freq; phase_init; ym]); % Minimise Least-Squares
if B(4)<0 % complement negative phase with 2pi
B(4) = B(4) + 2*pi;
end
yf = fit(B,t);
end
4 Kommentare
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Get Started with Curve Fitting Toolbox finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!