how to delete nan values from array columns without losing data from other columns

3 views (last 30 days)
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 Comments
Mathieu NOE
Mathieu NOE on 14 May 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
dareen
dareen on 14 May 2024
Edited: dareen on 14 May 2024
i appreciate your time and help ,sorry that the question is lengthy and not written in the most clear form, yeah for both files ,i tried to seprate them since each should yield some intersting observations ,= i was not sure if i should also keep the accelration and velocity since i am not sure implementation wise what to do , if any of the data before is needed in the later sections then we can work on the original file and i will try to learn and implement it in the the tided up versions and add whats needed , as for what i am trying to reach i firstly had another file of data from excel that helped find the spring constant and i ploted angular velocity intialy as a function of mass and now the new angular velocity when the system is osillating and slowing down as a function of mass here what i did for now i tried to copperate cftool since i thougth maybe there i can the sin and cos values yet failed mesriably not sure how to get the data from normal plots either

Sign in to comment.

Accepted Answer

Mathieu NOE
Mathieu NOE on 14 May 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 Comments

Sign in to comment.

More Answers (0)

Categories

Find more on Get Started with Curve Fitting Toolbox in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!