I am trying to justify an array containing pd.Timestamp
objects and np.nan
s using the method suggested here: Python: Justifying NumPy array (idea: mask the NaNs with a boolean array, sort the boolean array (justified_mask
) and assign the valid values to the new, sorted positions).
The only line that causes problems is when the Timestamp objects shall be inserted from the old masked array into the new masked array:
out[justified_mask] = arr[mask]
It throws the following error:
TypeError: float() argument must be a string or a number, not 'Timestamp'
without any Traceback coming from somewhere deeper in NumPy or so. Funnily, the masking operations on both sides of the equal sign work perfectly. Any idea how to solve this without major hassle? I know I could convert the Timestamp objects into integers by subtracting them from a date and the convert it back, but this is ot so easy as there are NaNs in the array as well. Is there any simpler solution?
EDIT: Reproducible example
times = np.array([[np.nan, pd.Timestamp('2018-11-07')], [np.nan, pd.Timestamp('2018-11-07')]])
Ok, sorry, I forgot to mention that I had to switch the invalid_val to accept a None
and let pd.isnull()
filter the NaNs out, making the justify function look like this:
def justify(a, invalid_val=0, axis=1, side='left'):
if invalid_val is np.nan:
mask = ~np.isnan(arr)
elif (invalid_val is not np.nan) and (invalid_val is not None):
mask = arr != invalid_val
else:
mask = ~pd.isnull(arr)
justified_mask = np.sort(mask, axis=axis)
if (side == 'up') | (side == 'left'):
justified_mask = np.flip(justified_mask, axis=axis)
out = np.full(arr.shape, np.nan)
if axis == 1:
out[justified_mask] = arr[mask]
else:
out.T[justified_mask.T] = arr.T[mask.T]
If you then run:
utils.justify(times, side='left', invalid_val=None)
you get the above error.