Получить индексы минимальных значений для каждой строки в двумерном массиве np.array, если минимальное значение удовлетворяет условию - PullRequest
2 голосов
/ 05 марта 2019

У меня есть 2D np.array с размером 1000 (rows) x 12 (columns).

Мне нужно получить индексы тех значений, которые ниже 1.5.
Если строка содержит более одного значения, которое удовлетворяет этому условию, тогда мне нужно сохранить только индексы самого низкого значения.

Я был бы очень доволен использованием idx1,idx2=np.where(x < 1.5), но иногда это возвращает несколько индексов, которые находятся в одинаковых строках. Конечно, я мог бы перебрать все повторяющиеся строки в idx1 и сохранить только те индексы, значения которых в x - самые низкие, но мне было интересно, есть ли более питонический способ.

Спасибо

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Вы можете просто сделать это:

# First index is all rows
idx1 = np.arange(len(x))
# Second index is minimum values
idx2 = np.argmin(m, axis=1)
# Filter rows where minimum is not below threshold
valid = x[idx1, idx2] < 1.5
idx1 = idx1[valid]
idx2 = idx2[valid]
0 голосов
/ 05 марта 2019

Один из способов - использовать массив массива . Давайте определим следующее случайное значение ndarray:

a = np.random.normal(1,2,(4,2))

print(a.round(2))
array([[ 1.41, -0.68],
       [-1.53,  2.74],
       [ 1.19,  2.66],
       [ 2.  ,  1.26]])

Мы можем определить замаскированный массив с помощью:

ma = np.ma.array(a, mask = a >= 1.5)

print(ma.round(2))
[[1.41 -0.68]
 [-1.53 --]
 [1.19 --]
 [-- 1.26]]

Чтобы иметь дело со строками без значений ниже порога, вы можете сделать:

m = ma.mask.any(axis=1)
# array([ True,  True,  True,  True])

Который будет содержать False, если в данной строке нет допустимых значений. А затем возьмите np.argmin поверх маскированного массива, чтобы получить столбцы с минимальными значениями ниже 1,5:

np.argmin(ma, axis=1)[m]
# array([1, 0, 0, 1])

А для строк вы можете сделать:

np.flatnonzero(m)
# array([0, 1, 2, 3])
...