Python: нахождение индекса строки значения в 2D-массиве при выполнении условия

#arrays #numpy #numpy-ndarray

#массивы #numpy #numpy-ndarray

Вопрос:

У меня есть 2D-массив PointAndTangent размером 8500 x 5. Данные расположены по строкам с 8500 строками данных и 5 значениями данных для каждой строки. Мне нужно извлечь индекс строки элемента в 4-м столбце, когда это условие выполнено, для любого s :

 abs(PointAndTangent[:,3] - s) <= 0.005
  

Мне просто нужен индекс строки первого соответствия для вышеуказанного условия. Я попытался использовать следующее:

 index = np.all([[abs(s - PointAndTangent[:, 3])<= 0.005], [abs(s - PointAndTangent[:, 3]) <= 0.005]], axis=0)

i = int(np.where(np.squeeze(index))[0])
  

который не работает. Я получаю следующую ошибку:

 i = int(np.where(np.squeeze(index))[0])

TypeError: only size-1 arrays can be converted to Python scalars
  

Я не настолько хорошо разбираюсь в NumPy на Python. Любые предложения были бы замечательными. Я пытаюсь избежать использования for цикла, поскольку это небольшая часть огромной симуляции, которую я пытаюсь.

Спасибо!

Возможное решение Я использовал следующее

 idx = (np.abs(PointAndTangent[:,3] - s)).argmin()
  

Кажется, это работает. Он возвращает индекс строки ближайшего значения к s в 4-м столбце.

Комментарии:

1. Вы хотите np.argwhere(abs(PointAndTangent[:, 4] - s) <= 0.005) ?

2. Я не думаю, что это работает. Я получаю 0 для любого s .

3. @ShubhamSubhnil. Это потому, что первая строка совпадает

4. Я не совсем уверен, что вас сбивает с толку, но, надеюсь, мой ответ поможет

Ответ №1:

Вы были почти на месте. np.where является одной из наиболее часто используемых функций в numpy. В половине случаев вы действительно хотите np.nonzero , а в другой половине вы хотите напрямую использовать логическую маску. В вашем случае вы хотите np.flatnonzero или np.argmax :

 mask = abs(PointAndTangent[:,3] - s) <= 0.005
  

mask это 1D массив с единицами, где условие выполнено, и нулями в другом месте. Вы можете получить индексы всех значений с flatnonzero и выбрать первый:

 index = np.flatnonzero(mask)[0]
  

В качестве альтернативы, вы можете выбрать первый непосредственно с помощью argmax :

 index = np.argmax(mask)
  

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

Оба могут быть записаны как однострочные путем замены mask на выражение, которое было присвоено ему.