То, что у вас сейчас выглядит отлично. Но поскольку вы спрашиваете о других способах достижения желаемой функциональности: вы можете создать одномерную логическую маску, равную True
или False
для каждого индекса строки. Вот пример.
>>> import numpy as np
>>> np.random.seed(444)
>>> shape = 15, 4
>>> mat = np.random.randint(low=0, high=10, size=shape)
>>> mat
array([[3, 0, 7, 8],
[3, 4, 7, 6],
[8, 9, 2, 2],
[2, 0, 3, 8],
[0, 6, 6, 0],
[3, 0, 6, 7],
[9, 3, 8, 7],
[3, 2, 6, 9],
[2, 9, 8, 9],
[3, 2, 2, 8],
[1, 5, 6, 7],
[6, 0, 0, 0],
[0, 4, 8, 1],
[9, 8, 5, 8],
[9, 4, 6, 6]])
# The thresholds for x, y, z, respectively
>>> lower = np.array([5, 5, 4])
>>> upper = np.array([6, 6, 7])
>>> idx = len(lower)
# Parentheses are required here. NumPy boolean ops use | and &
# which have different operator precedence than `or` and `and`
>>> mask = np.all((mat[:, :idx] < lower) | (mat[:, :idx] > upper), axis=1)
>>> mask
array([False, False, True, True, False, False, True, False, True,
True, False, False, True, False, False])
Теперь индексирование mat
по mask
ограничит его индексами строк, где mask
равно True
:
>>> mat[mask]
array([[8, 9, 2, 2],
[2, 0, 3, 8],
[9, 3, 8, 7],
[2, 9, 8, 9],
[3, 2, 2, 8],
[0, 4, 8, 1]])
Что немного отличается в этом подходе, так это то, что он масштабируемый: вместо того, чтобы указывать каждое условие координат по отдельности, вы можете указать их в двух массивах, один для верхнего порога и один для нижнего, а затем воспользоваться преимуществами NumPy. векторизация и трансляция для создания маски.
np.all()
говорит, проверяет, что все значения True
, по строкам. Он фиксирует условия "и" из вашего вопроса, в то время как оператор |
фиксирует "или".