I have a NumPy array a
like the following:
>>> str(a)
'[ nan nan nan 1.44955726 1.44628034 1.44409573\n 1.4408188 1.43657094 1.43171624 1.42649744 1.42200684 1.42117704\n 1.42040255 1.41922908 nan nan nan nan\n nan nan]'
I want to replace each NaN with the closest non-NaN value, so that all of the NaN's at the beginning get set to 1.449...
and all of the NaN's at the end get set to 1.419...
.
I can see how to do this for specific cases like this, but I need to be able to do it generally for any length of array, with any length of NaN's at the beginning and end of the array (there will be no NaN's in the middle of the numbers). Any ideas?
I can find the NaN's easily enough with np.isnan()
, but I can't work out how to get the closest value to each NaN.
I got something like this
It's a bit clunky though given it's split up in two lines with nested inline if's in one of them.
NaN
s have the interesting property of comparing different from themselves, thus we can quickly find the indexes of the non-nan elements:it's now easy to replace the nans with the desired value:
Finally, we can put this in a function:
edit
Ouch, coming from C++ I always forget about list ranges... @aix's solution is way more elegant and efficient than my C++ish loops, use that instead of mine.
A recursive solution!
The following will do it:
This is a straight
numpy
solution requiring no Python loops, no recursion, no list comprehensions etc.As an alternate solution (this will linearly interpolate for arrays
NaN
s in the middle, as well):This yields:
I came across the problem and had to find a custom solution for scattered NaNs. The function below replaces any NaN by the first number occurrence to the right, if none exists, it replaces it by the first number occurrence to the left. Further manipulation can be done to replace it with the mean of boundary occurrences.
Result is: