Нахождение расстояния до следующего более высокого значения в панде - PullRequest
1 голос
/ 15 октября 2019

У меня есть фрейм данных, содержащий значения с плавающей запятой

my_df = pd.DataFrame([1,2,1,4,3,2,5,4,7])

Я пытаюсь найти для каждого числа, когда (сколько индексов нужно переместить вперед ), пока я не найдуследующее число больше текущего числа, если большего числа нет, я помечаю его некоторым значением (например, 999999).

Поэтому для приведенного выше примера правильный ответ должен быть

result = [1,2,1,3,2,1,2,1,999999]

В настоящее время я решил эту проблему с помощью очень медленного двойного цикла с itertuples (что означает O (n ^ 2))

Есть ли более разумный способ сделать это?

1 Ответ

1 голос
/ 15 октября 2019

Вот однозначное основанное на использовании вещания:

a = my_df.squeeze().to_numpy() # my_df.squeeze().values for versions 0.24.0.<

diff_mat = a - a[:,None]
result = (np.triu(diff_mat)>0).argmax(1) - np.arange(diff_mat.shape[1])
result[result <= 0] = 99999

print(result)

array([    1,     2,     1,     3,     2,     1,     2,     1, 99999],
      dtype=int64)

Где diff_mat - матрица расстояний, и мы ищем значения из главной диагоналии далее, которые больше 0:

array([[ 0,  1,  0,  3,  2,  1,  4,  3,  6],
       [-1,  0, -1,  2,  1,  0,  3,  2,  5],
       [ 0,  1,  0,  3,  2,  1,  4,  3,  6],
       [-3, -2, -3,  0, -1, -2,  1,  0,  3],
       [-2, -1, -2,  1,  0, -1,  2,  1,  4],
       [-1,  0, -1,  2,  1,  0,  3,  2,  5],
       [-4, -3, -4, -1, -2, -3,  0, -1,  2],
       [-3, -2, -3,  0, -1, -2,  1,  0,  3],
       [-6, -5, -6, -3, -4, -5, -2, -3,  0]], dtype=int64)

Для этого у нас есть np.triu:

np.triu(diff_mat)

array([[ 0,  1,  0,  3,  2,  1,  4,  3,  6],
       [ 0,  0, -1,  2,  1,  0,  3,  2,  5],
       [ 0,  0,  0,  3,  2,  1,  4,  3,  6],
       [ 0,  0,  0,  0, -1, -2,  1,  0,  3],
       [ 0,  0,  0,  0,  0, -1,  2,  1,  4],
       [ 0,  0,  0,  0,  0,  0,  3,  2,  5],
       [ 0,  0,  0,  0,  0,  0,  0, -1,  2],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  3],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0]], dtype=int64)

И проверяя, которые больше 0, и принимаяargmax логического значения ndarray мы найдем первое значение больше 0 в каждой строке:

(np.triu(diff_mat)>0).argmax(1)
array([1, 3, 3, 6, 6, 6, 8, 8, 0], dtype=int64)

Нам нужно только вычесть соответствующее смещение из главной диагонали в начало

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...