0

I have an array that has about 70,000 rows that look like the following:

A = [ 1 2 3 4 5 6 0 723 1 22

      1 2 3 4 5 7 0 NaN 2 10 

      etc..                 ]

I would like to replace all NaN values in my array with the preceding value in the same column as the NaN value so that I would have something like this:

B = [ 1 2 3 4 5 6 0 723 1 22

      1 2 3 4 5 7 0 723 2 10 

      etc..                 ]

Since the array has about 70,000 rows, I am guessing some sort of loop would be the best way to achieve this. Using the following:

for ii = 1:size(A,2)
        I = A(1,ii);
        for jj = 2:size(A,1)
            if isnan(A(jj,ii))
                A(jj,ii) = I;
            else
                I  = A(jj,ii);
            end
        end
        end

I have been able to make a loop that replaces the whole row with the preceding row, but I am unsure how to modify it to target only NaN values. Any help would be greatly appreciated!

2 Answers 2

1

As long as there are now NaN's in the first row, you can just replace the values directly:

for ii = 1:size(A,2)
    for jj = 2:size(A,1)
        if isnan(A(jj,ii))
            A(jj,ii) = A(jj-1,ii);
        end
    end
end

Which avoids creating a second matrix B.

I think you're right, an you do need to use for-loops since your matrix is so large, but here is a non-for loop version anyway:

while(any(isnan(A(:))))
    A(find(isnan(A)))=A(find(isnan(A))-1)
end
Sign up to request clarification or add additional context in comments.

6 Comments

Why the while loop? The find line does the job by itself, doesn't it?
@LuisMendo if there are two or more NaN's on top of each other you need to repeat the process, because the bottom NaN will be replaced by the NaN above it.
Got it. The OP doesn't say what to do if there are several NaN's together on top of each other, but this is a good generalization. +1 already
Now I see the OP's last pseudocode part does "say" that :-)
@LuisMendo yeah it's not explicitly stated, but neither is what happens if there is a NaN in the top row!
|
1

Not sure why the I = A(1, ii); or the else branch is needed. If a NaN is found, just replace it with the value from the previous row:

for ii = 1:size(A,2)
    for jj = 2:size(A,1)
        if (isnan(A(jj,ii)))
            A(jj,ii) = A(jj-1, ii); %jj-1 is the previous row
        end
    end
end

1 Comment

You're welcome, @ficus. If this or any answer has solved your question please consider accepting it by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.