#python #arrays #numpy #partition
#python #массивы #numpy #раздел
Вопрос:
Предположим, что у меня есть множество разделов P
по интервалу [0,1)
. P
имеет длину N
. Например:
P = np.array([0,0.05,0.1,0.3,0.7,1])
которое делится [0,1)
на следующие интервалы:
[0,0.05), [0.05,0.1), [0.1,0.3), [0.3,0.7) , [0.7,1)
У меня есть другой массив U
длины K
более [0,1)
, элементы которого находятся u i/K
для i = 0,...,K-1
где 0<u<1/K
. Например
U = np.array([0.03,0.13,0.23,0.33,0.43,0.53,0.63,0.73,0.83,0.93])
Я хочу подсчитать количество элементов в, U
которые попадают в каждый раздел j = 0, ..., N-1
. В этом примере мы имеем
C = np.array([1,0,2,4,3])
Есть ли способ сделать это без использования цикла?
Ответ №1:
Одним из способов является использование np.searchsorted
для получения индексов, в которые U
должны быть вставлены элементы P
для поддержания порядка, с последующим np.bincount
подсчетом количества вхождений каждого индекса:
np.bincount(np.searchsorted(P,U))[1:]
# array([1, 0, 2, 4, 3])
Или с np.digitize
предположением, что ячейки всегда монотонно увеличиваются:
np.bincount(np.digitize(U,P))[1:]
# array([1, 0, 2, 4, 3])
Подробные сведения
P = np.array([0,0.05,0.1,0.3,0.7,1])
U = np.array([0.03,0.13,0.23,0.33,0.43,0.53,0.63,0.73,0.83,0.93])
Как упоминалось, np.searchsorted
вернет индексы, в которые U
должны быть вставлены элементы в P
, чтобы последние оставались упорядоченными:
s = np.searchsorted(P,U)
# array([1, 3, 3, 4, 4, 4, 4, 5, 5, 5])
Следующее, что мы хотим, это подсчитать количество вхождений каждого индекса. Для этого мы можем использовать np.bincount
, который будет делать именно то, что мы хотим. Обратите внимание, что возвращаемый массив бинирования будет содержать до np.amax(x) 1
значений, что означает, что он также выведет количество 0
пропущенных значений, 2
в данном случае, которое соответствует интервалу [0.05,0.1)
:
np.bincount(s)[1:]
# array([1, 0, 2, 4, 3])