I have Matrix A as:
A = [4 5 9 Nan 8 3 4 4
3 5 9 7 8 3 4 4
4 4 5 8 6 5 4 4
4 5 9 Nan 8 3 4 4
3 5 1 Nan 5 4 9 1
7 2 2 8 5 5 6 1
3 4 1 2 5 4 9 8
3 5 1 4 1 1 1 9
3 4 5 2 3 4 6 6
3 4 5 Nan 3 4 6 6];
There are some NaN values in column 4. I want to find similar rows in matrix A and give relevant value of their column 4 to those NaN cells. In case if all cells in a row aren't matching with the row of Nan, find the most matchable (perhaps weighting option).
Results can be similar to B:
B = [4 5 9 7 8 3 4 4
3 5 9 7 8 3 4 4
4 4 5 8 6 5 4 4
4 5 9 7 8 3 4 4
3 5 1 2 5 4 9 1
7 2 2 8 5 5 6 1
3 4 1 2 5 4 9 8
3 5 1 4 1 1 1 9
3 4 5 2 3 4 6 6
3 4 5 2 3 4 6 6];
% first and fourth rows Nan values got value 7 from second row because of most similarity % fifth row Nan value got value 2 from the seventh row because of most similarity % tenth row Nan value got value 2 from the ninth row because of exact similarity

 Akzeptierte Antwort

Stephen23
Stephen23 am 9 Sep. 2018
Bearbeitet: Stephen23 am 9 Sep. 2018

0 Stimmen

>> X = isnan(A(:,4));
>> C = [1:3,5:8];
>> D = sum(bsxfun(@minus,permute(A(~X,C),[1,3,2]),permute(A(X,C),[3,1,2])).^2,3);
>> [~,Y] = min(D,[],1);
>> Z = find(~X);
>> A(X,4) = A(Z(Y),4)
A =
4 5 9 7 8 3 4 4
3 5 9 7 8 3 4 4
4 4 5 8 6 5 4 4
4 5 9 7 8 3 4 4
3 5 1 8 5 4 9 1
7 2 2 8 5 5 6 1
3 4 1 2 5 4 9 8
3 5 1 4 1 1 1 9
3 4 5 2 3 4 6 6
3 4 5 2 3 4 6 6
>> Z(Y) % the rows used
ans =
2
2
6
9

5 Kommentare

Lu Xi
Lu Xi am 9 Sep. 2018
Thanks @Stephen Cobeldick. Do you know why some rows are being replaced? For example, an extra column was added at the end (as sorting number) and as you can see some rows are missing (#1,#4,#5,#10) in the result. Are you able to keep all original rows and just update rows with NaN value?
A = [4 5 9 nan 8 3 4 4 1
3 5 9 7 8 3 4 4 2
4 4 5 8 6 5 4 4 3
4 5 9 nan 8 3 4 4 4
3 5 1 nan 5 4 9 1 5
7 2 2 8 5 5 6 1 6
3 4 1 2 5 4 9 8 7
3 5 1 4 1 1 1 9 8
3 4 5 2 3 4 6 6 9
3 4 5 nan 3 4 6 6 10];
And after code run:
A = [3 5 9 7 8 3 4 4 2
3 5 9 7 8 3 4 4 2
4 4 5 8 6 5 4 4 3
3 5 9 7 8 3 4 4 2
7 2 2 8 5 5 6 1 6
7 2 2 8 5 5 6 1 6
3 4 1 2 5 4 9 8 7
3 5 1 4 1 1 1 9 8
3 4 5 2 3 4 6 6 9
3 4 5 2 3 4 6 6 9]
Stephen23
Stephen23 am 9 Sep. 2018
Bearbeitet: Stephen23 am 9 Sep. 2018
@Lu Xi: sorry, I misinterpreted your original question to mean that you wanted to replace the whole row, but now I see that you only want to replace the NaN in column 4. This is easy to do, just change the last line of my answer to this:
A(X,4) = A(Z(Y),4)
To ignore the last column when making the comparison you should also define C like this:
C = [1:3,5:8];
This is the output when I made those two changes and try your new matrix:
A =
4 5 9 7 8 3 4 4 1
3 5 9 7 8 3 4 4 2
4 4 5 8 6 5 4 4 3
4 5 9 7 8 3 4 4 4
3 5 1 8 5 4 9 1 5
7 2 2 8 5 5 6 1 6
3 4 1 2 5 4 9 8 7
3 5 1 4 1 1 1 9 8
3 4 5 2 3 4 6 6 9
3 4 5 2 3 4 6 6 10
Lu Xi
Lu Xi am 9 Sep. 2018
Thanks @Stephen Cobeldick for corrections and extra note. It's very close to what I am looking for. Is there any alternative function to replace bsxfun function. Because when I use a larger input, I am getting the following error:
Error using bsxfun
Requested 126074x2459x7 (16.2GB) array exceeds maximum array size preference. Creation of arrays greater than this limit
may take a long time and cause MATLAB to become unresponsive. See array size limit or preference panel for more
information.
Stephen23
Stephen23 am 9 Sep. 2018
Bearbeitet: Stephen23 am 9 Sep. 2018
@Lu Xi: for such a large matrix A you can use a loop, and check one NaN row on each iteration:
X = isnan(A(:,4));
C = [1:3,5:8];
Z = find(~X);
for k = reshape(find(X),1,[])
[~,Y] = min(sum(bsxfun(@minus,A(~X,C),A(k,C)).^2,2));
A(k,4) = A(Z(Y),4);
end
Giving:
A =
4 5 9 7 8 3 4 4 1
3 5 9 7 8 3 4 4 2
4 4 5 8 6 5 4 4 3
4 5 9 7 8 3 4 4 4
3 5 1 8 5 4 9 1 5
7 2 2 8 5 5 6 1 6
3 4 1 2 5 4 9 8 7
3 5 1 4 1 1 1 9 8
3 4 5 2 3 4 6 6 9
3 4 5 2 3 4 6 6 10
Lu Xi
Lu Xi am 9 Sep. 2018
Excellent @Stephen Cobeldick!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Gefragt:

am 9 Sep. 2018

Kommentiert:

am 9 Sep. 2018

Community Treasure Hunt

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

Start Hunting!

Translated by