how to delete nan values from array columns without losing data from other columns
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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 commentaires
Mathieu NOE
le 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
Réponse acceptée
Mathieu NOE
le 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 commentaires
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Get Started with Curve Fitting Toolbox dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!