#python #python-3.x #performance #numpy
Вопрос:
У меня есть 2D numpy array
. Каждая строка содержит данные с временной выборкой, которые должны соответствовать нескольким различным возможным критериям.
Для каждой строки необходимо применять несколько различных критериев. Каждая строка-это данные из системы, и каждый критерий представляет собой различную ситуацию, которую можно обнаружить. Условие критериев определяется, если выбранные столбцы в строке находятся в определенном интервале (больше и меньше определенных значений).
Есть ли способ сделать это очень быстро и эффективно numpy
? Я осматривался и на самом деле не нашел способа, хотя я новичок в numpy
этом .
Я думал о механизме хэширования, таком как хранение некоторого хэша для каждой строки и проверка соответствия хэша критериев хэшу этой строки. Однако механизм хэширования будет работать только с фиксированными значениями, а не с диапазонами значений. Поэтому это было бы на самом деле неприменимо.
Примеры данных:
import numpy as np
myData = np.array([[7.241, 7.123, 9.0, 1.2, 1.0, 1.5, 67.14, 162.32], [8.123, 10.4, 7.68, 1.6,0.7, 2.3, 21.2, 175.2]])
Примерные условия:
Criteria #1:
condition 1 : column 1 must be greater than 6 and less than 7
condition 2 : column 4 must be greater than 0 and less than 2
condition 3 : column 6 must be greater than 10 and less than 50
(conditions are 'and' operation, so all conditions must be met for criteria to be met or not)
Criteria #2:
condition 1 : column 3 must be greater than 10 and less than 22
condition 2 : column 4 must be greater than 9 and less than 15
Я думал о том numpy
, поддерживает ли, так сказать, какое-то регулярное выражение в этом отношении. Существуют ли какие-либо механизмы или методы, numpy
которые могли бы эффективно способствовать этому?
Приведенный выше пример прост, но в реальном применении матрица будет содержать несколько сотен строк, и для каждой строки может быть несколько десятков критериев для оценки.
Комментарии:
1.
(myData[:,0}>6)amp;(myData[:,0]<7)
создает 1d логический массив, по одному элементу в строке (все ложно!). Аналогично для других тестов столбцов.2. Несколько сотен строк-это крошечное число на любой современной машине.
Ответ №1:
Первый вариант: простое векторизованное сравнение:
c1 = (data[:, 0] > 6) amp; (data[:, 0] < 7) amp; (data[:, 3] > 0) amp; (data[:, 3] < 2) amp; (data[:, 5] > 10) amp; (data[:, 5] < 50)
c1
является логической маской местоположений, в которых строка запускает критерий 1. Вы можете использовать его в качестве индекса в первом измерении data
.
Второй вариант: извлеките интересующие столбцы и сравните их с верхним и нижним критериями одновременно:
c1lower = [6, 0, 10]
c1upper = [7, 2, 50]
c1cols = data[:, [0, 3, 5]] # this is a copy
c1 = ((c1cols > c1lower) amp; (c1cols < c1upper)).all(1)
Копирование данных может быть медленнее, но объединение их по всей строке должно быть быстрее.
В обоих случаях вы можете преобразовать логическую маску в числовой индекс с помощью np.where
, np.nonzero
, np.flatnonzero
или np.argwhere
.