Я пытаюсь обосновать массив, содержащий pd.Timestamp
объекты и np.nan
s, используя предложенный здесь метод: Python: Обоснование массива NumPy (идея: замаскировать NaN с помощью логического массива, отсортировать логический массив (justified_mask
) и присваивать действительные значения новым, отсортированным позициям).
Единственная строка, которая вызывает проблемы, - это когда объекты Timestamp должны быть вставлены из старого замаскированного массива в новый замаскированный массив:
out[justified_mask] = arr[mask]
Выдает следующую ошибку:
TypeError: аргумент float () должен быть строкой или числом, а не
'Отметка'
без какого-либо отслеживания, идущего откуда-то из глубины NumPy или около того. Как ни странно, маскирующие операции с обеих сторон знака равенства работают отлично. Есть идеи, как решить эту проблему без особых хлопот?
Я знаю, что мог бы преобразовать объекты Timestamp в целые числа, вычтя их из даты и преобразовав обратно, но это не так просто, поскольку в массиве также есть NaN. Есть ли более простое решение?
РЕДАКТИРОВАТЬ: Воспроизводимый пример
times = np.array([[np.nan, pd.Timestamp('2018-11-07')], [np.nan, pd.Timestamp('2018-11-07')]])
Хорошо, извините, я забыл упомянуть, что мне пришлось переключить invalid_val для принятия None
и позволить pd.isnull()
отфильтровывать NaN, чтобы функция justify выглядела следующим образом:
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]
Если вы затем запустите:
utils.justify(times, side='left', invalid_val=None)
Вы получаете вышеуказанную ошибку.