Алгоритм поиска в двумерном массиве
Возникла необходимость написать некий анализатор, который рассчитывает выживаемость пациентов. Упрощенно его алгоритм работы выглядит так:
Некоторое рассчитанное врачом значение VAL [1] сравнивается со значениями в двумерном массиве [2]. Сравнение должно происходить только с данными из первого столбца.
Значение VAL может либо точно совпасть с одним из значений в массиве, не совпасть ни с одним из значений в массиве, но быть очень близко к одному из них; выйти за диапазон значений в массиве.
Если значение VAL точно совпало с одним из значений в массиве, алгоритм должен вывести врачу следующее значение в строке [3] (например, как на картинке, VAL = 11 и алгоритм выведет в print следующее значение в строке - 280).
На данный момент я написал упрощенную модель [ 2 ] этапа. Код ниже:
import numpy as np
a = np.array([
[1, 244], [2, 211], [3, 466], [4, 698], [5, 899], [6, 109], [7, 129], [8, 140],
[9, 168], [10, 188], [11, 280], [12, 282], [13, 245], [14, 256], [15, 258],
[16, 305], [17, 352], [18, 345], [19, 365], [20, 348], [21, 440],[22, 424],
[23, 444], [24, 446], [25, 477], [26, 479], [27, 571], [28, 573], [29, 557],
[30, 577]
], int)
val = 11
if val in a:
print('СОВПАТЕНИЕ ЕСТЬ!')
idx = np.where(a == val)
row = idx[0][0]
print(f'Связанное значение: {a[row][1]}')
else:
print('СОВПАДЕНИЙ НЕТ!')
nearest_val = a.flat[np.abs(a - val).argmin()]
print(f'Ближайшее значение: {nearest_val}')
idx = np.where(a == nearest_val)
row = idx[0][0]
print(f'Связанное значение: {a[row][1]}')
Модель работает с двумя сценариями: когда значение VAL точно совпадает с одним из значений в массиве и когда точного значения нет, но, есть близкое к нему. Третий пока не писал. Используемый в модели массив небольшой всего 30 значений, тот, который будет использоваться в полноценном калькуляторе содержит более 5000 значений на один столбец и, как мне кажется, в такой ситуации логично воспользоваться инструментарием Numpy.
Я хотел бы услышать мнение более опытных в этих делах коллег:
Насколько вменяемо реализована его логика? Есть ли более грамотный вариант с точки зрения опытного программиста?
Алгоритм ищет сразу по всем значениям в массиве, а как можно ограничить поиск только одним столбцом?
В модели массив небольшой, но, тот, что будет использоваться в полноценной версии калькулятора содержит более 5000 значений на столбец. Как лучше организовать такой массив? Сделать его внешним файлом? Или перенести все значения в сам код?
Как можно ли как-то вытаскивать значения индексов переменных находящихся в массиве и использовать их как обычные int-значения? В модели я это сделал при помощи:
idx = np.where(a == val)
row = idx[0][0]
Это для точного совпадения. Но, у меня есть большие сомнения в правильности такого подхода.
ДОПОЛНЕНИЕ: В процессе изучения замечаний strawdog получилось собрать такой вариант алгоритма:
import numpy as np
a = np.array([
[1, 244], [2, 211], [3, 466], [4, 698], [5, 899], [6, 109], [7, 129], [8, 140],
[9, 168], [10, 188], [11, 280], [12, 282], [13, 245], [14, 256], [15, 258],
[16, 305], [17, 352], [18, 345], [19, 365], [20, 348], [21, 440],[22, 424],
[23, 444], [24, 446], [25, 477], [26, 479], [27, 571], [28, 573], [29, 557],
[30, 577]
], int)
val = 2
row = a[np.abs(a[:,0] - val).argmin()]
if val in a[:,0]:
print(f'СОВПАТЕНИЕ ЕСТЬ!\n'
f'Связанное значение: {a[np.where(a == row)][1]}')
else:
print(f'СОВПАДЕНИЙ НЕТ!\n'
f'Ближайшее значение: {a[np.where(a == row)][0]}\n'
f'Связанное значение: {a[np.where(a == row)][1]}')
В свою очередь он очень похож на вариант предложенный Serge3leo. Поэтому на нём пока и остановлюсь, в дальнейшем, дополню ответ добавлением сценариев обработки варианта вылета значений VAL за диапазон в массиве. Большое спасибо strawdog и Serge3leo за помощь в решении задачи!