dede
dede

Reputation: 1181

Find the value that corresponds to an index

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.

Upvotes: 1

Views: 353

Answers (2)

beaker
beaker

Reputation: 16810

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

Upvotes: 2

Coriolis
Coriolis

Reputation: 396

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

Upvotes: 2

Related Questions