I have the following variables:
x = [0 1 2 2 3 4 5 6 7 8 9];
y = [0 1 2 nan 3 4 5 6 7 8 9];
I would like to pass 'y' through an equation to give 'y2', for example:
y2 = y.*2;
Note this is just an example. The real equation I have is more complicated. The 'real' equation does not allow nans to be within the vector (as one value depends on the last).
If I can't have nans passing through the equation, however, I can type
y2 = y(~isnan(y)).*2;
y2 =
0 2 4 6 8 10 12 14 16 18
This removes the nan and then performs the calculation.
How can I make 'y2' to be back to the same length as 'x' i.e. with a nan as the fourth value?
Something like:
y2 =
0 2 4 NaN 6 8 10 12 14 16 18
The reason I'm doing this is that I want to plot 'y2' against 'x' and thus they must be the same size.
I realize that I can do
x2 = x(~isnan(y))
and then just plot 'x2' against 'y2' but I would like to find a way of doing it the way I specify above.
Store the NaN indices somewhere and then use those to input the new values into the right places and then plug back in the NaN values too.
Code
%%// Define function
func1 = #(x)x*2;
%%// Input data - y
y = [0 1 2 nan 3 4 5 6 7 8 9];
%%// Store NaN indices
nan_ind = isnan(y)
%%// Process data on the function
y2(~nan_ind) = func1(y(~nan_ind))
y2(nan_ind) = NaN
Related
Suppose I initialized two vectors,
x=[1 2 3 4 5]';
y=[6 7 8 9 10]';
both representing a column matrix, or vector. Now,
z=[x;y];
The z vector will be combination of the two, in a similar column format. y vector will be in continuation to the x vector by this method.
But what should be the approach if I wanted y to be in continuation from a certain given position, leaving the remaining values in between as blank. For example, I want the continuation of y from 8th position to get an output of z as:-
1
2
3
4
5
NaN
NaN
6
7
8
9
10
Just count, how many blanks (NaN) do you need using the desired position and the number of elements of x, and assemble your output z:
% Input
x = [1 2 3 4 5]'
y = [6 7 8 9 10]'
% Position
pos = 8;
% Add some code for checking numel(x) >= pos here...
% Output
z = [x; NaN(pos-numel(x)-1, 1); y]
x =
1
2
3
4
5
y =
6
7
8
9
10
z =
1
2
3
4
5
NaN
NaN
6
7
8
9
10
Meh, after some editing, I realized, that a comment would've been sufficient...
I have two dataset arrays, A and B. They are two different, independent measurements (e.g. smell and color of some object).
For each data entry in A and B, I have a time, t, and a location, p of the measurement. The majority of the smell and color measurements were taken at the same time and location. However, there are some times where data is missing (i.e. at some time there was no color measurement and only a smell measurement). Similarly, there are some locations where some data is missing (i.e. at some location there was only color measurement and no smell measurement).
I want to build arrays of A and B which have the same size where each row corresponds to a full set of all times and each column corresponds to a full set of all locations. If there is data missing, I want that entry to be NaN.
Below is an example of what I want to do:
%Inputs
A = [0 0 1 2 4; 1 1 3 3 2; 4 4 1 0 3];
t_A = [0.03 1.6 3.9]; %Times when A was measured (rows of A)
L_A = [1.0 2.9 2.98 4.2 6.33]; %Locations where A was measured (columns of A)
B = [10 13 10 10; 15 13 13 12; 14 14 13 12; 15 19 11 13];
t_B = [0.03 1.6 1.9 3.9]; %Times when B was measured (rows of B)
L_B = [2.1 2.9 2.98 5.0]; %Locations where B was measured (columns of B)
What I want is some code to transform these datasets into the following:
t = [0.03 1.6 1.9 3.9];
L = [1.0 2.1 2.9 2.98 4.2 5.0 6.33];
A_new = [0 NaN 0 1 2 NaN 4; 1 NaN 1 3 3 NaN 2; NaN NaN NaN NaN NaN NaN NaN; 4 NaN 4 1 0 NaN 3];
B_new = [NaN 10 13 10 NaN 10 NaN; NaN 15 13 13 NaN 12 NaN; NaN 14 14 13 NaN 12 NaN; NaN 15 19 11 NaN 13 NaN];
The new arrays, A_new and B_new, are the same size and the vectors t and L (corresponding to the rows and columns) are sequential. The original A had no data at t = 1.9 and thus at the 3rd row in A_new, there is all NaN values. Similarly for the columns 2 and 6 in A_new and columns 1, 5 and 7 in B_new.
How can I do this in MATLAB quickly for a large dataset?
Create a matrix of NaNs , use third output of the unique function to convert floating numbers to integer indexes and use matrix indexing to fill the matrices:
[t,~,it] = unique([t_A t_B]);
[L,~,iL] = unique([L_A L_B]);
A_new = NaN(numel(t),numel(L));
A_new(it(1:numel(t_A)),iL(1:numel(L_A))) = A;
B_new = NaN(numel(t),numel(L));
B_new(it(numel(t_A)+1:end),iL(numel(L_A)+1:end)) = B;
I have two matrices, A of size 1x30974 and B of size 55x30974. Matrix A contains values from 1 to to 30974, while matrix B (first row) contains values that are also elements of matrix A, yet they do not have to be in order.
So in a simple case, I would have:
A = [1 2 3 4 5 6 7 8];
B = [1 2 6 8; 20 21 22 23; 30 31 32 33];
I would like to compare A and B in a way that my output would return:
C = [1 2 3 4 5 6 7 8; 20 21 NaN NaN NaN 22 NaN 23; 30 31 NaN NaN NaN 32 NaN 33];
Saying differently, if the value in the first row of B is an element of A, then return all values in this column. If an element of A has no value in the first row of B, then the column is NaN.
In my case, the output would be of size 55x30974.
I guess that ismember could be the function I am looking for, but even then, how could I get the values of the column?
You should use both outputs from ismember. The first tells you if a value is present and the second gives you the index where it is found (or 0 if it isn't present):
[isMatch, index] = ismember(B(1, :), A);
C = nan(size(B, 1), numel(A));
C(:, index(isMatch)) = B(:, isMatch);
I have a cell array called output. Each cell within output contains a 1024 x 1024 matrix. I would like to threshold each matrix so that elements below a given value are set to NaN.
I tried using:
output(output < 100000) = NaN;
However, I feel that this is the wrong approach. Intuitively, I want to use a for loop, however, I don't think that will be the most efficient method possible.
Thoughts? Suggestions?
Thanks :)
it can be done with cellfun function!cell fun can implement a function on every cell (it's like for loop) Assume below example
first consider you have a variable named a in cell form.
a{1,1} =
1 2
3 4
a{2,1} =
1 2
5 5
a{1,2} =
4 5
1 2
a{2,2} =
5 5
5 5
in this cell i want to substitute entries with NaN if entry lower than 3
So I write below function for this purpose
function out = main_func()
%% define a
a{1,1}=[1 2;3 4];
a{1,2}=[4 5;1 2];
a{2,1}=[1 2;5 5];
a{2,2}=[5 5;5 5];
out=cellfun(#(T) cell_f(T),a,'uniformOutput',false); % using cell fun function
function x = cell_f(x)
x(x<3)=nan; % if entries lower that 3 then substitute with Nan
the output will be like below
ans{1,1} =
NaN NaN
3 4
ans{2,1} =
NaN NaN
5 5
ans{1,2} =
4 5
NaN NaN
ans{2,2} =
5 5
5 5
I have an array 2549x13 double (M).
Example lines:
-7.8095 -4.4135 -0.0881 2.5159 6.3142 6.9519 4.9788 2.9109 0.6623 -0.9269 0.3172 1.2445 -0.0730
4.5819 6.2371 5.8721 6.1824 5.2074 4.8656 5.0269 5.3340 3.6919 1.3608 -0.5443 0.2871 -1.2070
-6.2273 -3.7767 1.1829 2.8522 3.2428 0.5261 -3.5535 -7.7743 -8.4391 -9.8188 -6.0503 -5.8805 -7.7700
-2.2157 -3.2100 -4.4400 -3.5898 -0.8901 3.4061 6.5631 7.2028 4.3082 -0.7742 -5.0963 -3.1837 0.4372
5.5682 5.5393 3.4691 0.6789 1.7320 4.4472 3.7622 1.0194 -0.5362 -3.1721 -6.1281 -6.3959 -6.1932
0.9707 -0.2701 -3.8883 -8.8974 -7.0375 -1.5085 5.4171 6.0831 2.9852 -2.3474 -4.5637 -3.7378 1.3236
-2.811 0.0164 2.7208 5.7862 7.3344 8.3504 9.0635 8.4271 2.7669 -2.1403 -2.2003 -0.9940 0.7729
4.2382 3.3532 3.5475 7.9209 11.7933 14.3181 13.6289 12.9553 13.7464 14.1331 14.3814 16.7949 15.9003
-0.0539 -2.7059 -3.8141 -2.7531 -1.7465 0.9190 2.2220 0.7268 1.5436 1.0426 2.3535 3.0269 6.4798
I also have the indices of some values I need, 2549x5 double(inde).
Example lines:
4 5 6 7 8
0 1 2 3 4
3 4 5 6 7
6 7 8 9 10
-1 0 1 2 3
6 7 8 9 10
5 6 7 8 9
10 11 12 13 14
11 12 13 14 15
I want now to create a new array/matrix with the actual values. So, to find in the array M the values corresponding to the indices inde.
However, if the index (in inde) is equal to zero, I would like to take the values corresponding to the indeces 1,2,3,4 of that row.
If the index is -1 or 15, I would like to insert an NaN in the new array/matrix.
If the index is 14, I would like to take the values corresponding to 10,11,12,13.
So I would like to obtain:
2.5159 6.3142 6.9519 4.9788 2.9109
NaN 4.5819 6.2371 5.8721 6.1824
1.1829 2.8522 3.2428 0.5261 -3.5535
3.4061 6.5631 7.2028 4.3082 -0.7742
NaN
-1.5085 5.4171 6.0831 2.9852 -2.3474
7.3344 8.3504 9.0635 8.4271 2.7669
14.1331 14.3814 16.7949 15.9003 NaN
NaN
Very grateful to anyone who could help with this.
This will give you the desired array:
rows = size(M, 1); % number of rows in M and inde
cols = size(inde, 2); % number of columns in inde
N = [nan(rows, 2) M nan(rows, 2)]; % pad M with 2 columns of NaN values
% on left and right
inde = inde + 2; % change indices to account for padding
P = zeros(rows, cols); % preallocate result matrix
nanrow = nan(1, cols); % make a row of all NaN values
for row_num = 1:rows
P(row_num,:) = N(row_num, inde(row_num,:)); % get values from N
if sum(isnan(P(row_num,:))) > 1 % if 2 NaN values, original index was -1 or 15
P(row_num,:) = nanrow; % so make it all NaN's
end
end
(I dislike leaving that stray 2 in there when padding, but I was unsure what the expected result was for different numbers of columns of inde, if that's even a concern. Perhaps floor(cols/2)?)
Since MATLAB won't allow you to have matrices with rows of unequal length, for rows in which there are indices of -1 or 15, I've inserted a row of all NaN values. This can obviously be changed to whatever you prefer by modifying the line inside the if clause.
Results using M and inde from your example:
P =
2.51590 6.31420 6.95190 4.97880 2.91090
NaN 4.58190 6.23710 5.87210 6.18240
1.18290 2.85220 3.24280 0.52610 -3.55350
3.40610 6.56310 7.20280 4.30820 -0.77420
NaN NaN NaN NaN NaN
-1.50850 5.41710 6.08310 2.98520 -2.34740
7.33440 8.35040 9.06350 8.42710 2.76690
14.13310 14.38140 16.79490 15.90030 NaN
NaN NaN NaN NaN NaN
EDIT
I suggest not to mix numbers and characters in your matrix since it would become a cell-structure which is harder to handle.
So I assume for the rest of my answer that you want to put zeros (or any error value, -999 for instance is sometimes used) where you want to modify your data. Assuming A is your data matrix and i your indexes' matrix :
B=zeros(size(i));
for j=1:size(i,1)
if (prod(i(j,:))==0)
k=find(i(j,:)==0);
B(j,k+1:end)= A(j,i(j,k+1:end));
m=find(i(j,:)<0);
if (~isempty(m))
B(j,:)= 0;
end
else
B(j,:)= A(j,i(j,:));
end
end
I get :
2.5159 6.3142 6.9519 4.9788 2.9109
0 4.5819 6.2372 5.8722 6.1824
1.1830 2.8522 3.2429 0.5261 -3.5535
3.4061 6.5632 7.2028 4.3083 -0.7742
0 0 0 0 0
-1.5086 5.4171 6.0831 2.9853 -2.3475
7.3344 8.3505 9.0635 8.4271 2.7670