#python-3.x #numpy #floating-point #compare #precision
#python-3.x #numpy #с плавающей запятой #Сравнить #точность
Вопрос:
Как я могу сравнить два массива с разными размерами, но с приблизительными значениями с плавающей точкой? Например:
# I have two arrays
a = np.array( [-2.83, -2.54, ..., 0.05, ..., 2.54, 2.83] )
b = np.array( [-3.0, -2.9, -2.8, ..., -0.1, 0.0, 0.1, ..., 2.9, 3.0] )
# wherein len( b ) > len( a )
Что мне нужно, так это индекс where (учитывая эти два значения из обоих списков)
math.isclose( -2.54, -2.5, rel_tol=1e-1) == True
Ответ, который мне нужен, это что-то вроде
list_of_index_of_b = [1, 5, ..., -2]
Вот list_of_index_of_b
список с «координатами», где этот конкретный элемент b
является приблизительным к некоторому элементу a
. Не все элементы a
имеют приблизительное значение b
. Также:
len(list_of_index_of_b) == len(a)
Комментарии:
1. len(list_of_index_of_b) == len(a) ?
2. Если
a
иb
не слишком велики, простым методом было быnp.where(np.isclose(*np.ix_(a, b), rtol=1e-1))
.
Ответ №1:
Вы можете использовать широковещательную передачу. Это создает массив попарных различий между каждым элементом в a
и b
, который затем вы можете проверить на соответствие указанному допуску.
Конечно, это вычислительно неэффективно с точки зрения сложности, поскольку вы создаете массив размера |a|*|b|
и сравниваете каждое попарное расстояние с допуском, даже если одно из различий уже достаточно мало. Тем не менее, если один из |a|
или |b|
относительно мал, то этот подход может быть довольно быстрым, поскольку он является чисто numpy и не требует циклов.
a = np.array([1,5,6,7])
b = np.array([1.1,2,3,4.8,4.9,5,8])
rtol = 0.15
diff = a - b[:,None]
mask2d = (1/np.abs(b))*np.abs(a - b[:,None]) < rtol
mask = np.any(mask2d,axis=1)
Это можно объединить в одну строку:
indices = np.where(np.any((1/np.abs(b))*np.abs(a-b[:,None]) < rtol,axis=1))