интерполировать категориальные данные в python? (ближайшее / предыдущее значение) - PullRequest
0 голосов
/ 26 мая 2020

Как можно интерполировать категориальные (не с плавающей точкой или, в более широком смысле, нечисловые) данные в python?

Тестовые данные

Вот пример набора данных со строкой -значные значения y.

x = [1.4, 2.8, 3.1, 4.4, 5.2]
y = ['A', 'B', 'A', 'A', 'B']

Ожидаемые результаты

# with kind= 'nearest'
x_new = [1, 2, 3, 4, 5]
y_new = ['A', 'A', 'A', 'A', 'B']

# with kind= 'previous', fill_value = None
x_new = [1, 2, 3, 4, 5]
y_new = [None, 'A', 'B', 'A', 'A']

Я ожидал, что interp1d сможет выполнить работу с kind='nearest' или kind='previous', но, к сожалению, это не так.

1 Ответ

2 голосов
/ 26 мая 2020

Вы все равно можете использовать interp1d, если замените целевые точки индикаторами. Т.е. создать список всех уникальных значений - в вашем случае это будет ['A', 'B'], переход y будет показывать вместо строк (показатели преобразованы в float - все будет в порядке, если количество уникальных элементов может быть сохранено как float без потери точности).

После интерполяции вам просто нужно вернуть элементы с учетом результата интерполяции. Пока вы используете «предыдущий» или «ближайший», вы всегда будете получать значение с плавающей запятой, которое является одним из ваших исходных индикаторов.

UPD. Еще более простой вариант - использовать y_int = [float(i) for i in range(len(y))] в качестве входных данных для interp1d, а затем после того, как вы получите результат интерполяции, просто используйте его как индекс y.

Пример: kind='nearest'

from scipy.interpolate import interp1d
import numpy as np

x = [1.4, 2.8, 3.1, 4.4, 5.2]
y = ['A', 'B', 'A', 'A', 'B']

f = interp1d(x, range(len(y)), kind='nearest', fill_value=(0, len(y)-1), bounds_error=False)
y_idx = f(x_new)
y_new = [y[int(i)] for i in y_idx ]
# ['A', 'A', 'A', 'A', 'B']

Пример: kind='previous'

from scipy.interpolate import interp1d
import numpy as np

x = [1.4, 2.8, 3.1, 4.4, 5.2]
y = ['A', 'B', 'A', 'A', 'B']
f = interp1d(x, range(len(y)), kind='previous', fill_value=-1, bounds_error=False)
y_idx = f(x_new)
y_new = [y[int(i)] if i != -1 else None for i in y_idx]
# [None, 'A', 'B', 'A', 'A']
...