У меня есть список чисел, которые я хочу отсортировать по ячейкам и найти медиану каждой ячейки.Если бы у всех бункеров было одинаковое количество точек данных, это было бы легко сделать достаточно эффективно, используя массивы numpy:
import numpy as np
indices=np.array([0,1,0,1,1,2,3,3,3,2,0,2])
length=np.max(indices)+1
data = np.arange(len(indices))
binned = np.array([data[indices == i] for i in range(length)])
Значения бин-данных (в массиве binned
) равны
array([[ 0, 2, 10],
[ 1, 3, 4],
[ 5, 9, 11],
[ 6, 7, 8]])
Медиана каждого бина:
np.median(binned, axis=1)
Результат:
array([2., 3., 9., 7.])
Однако, если список таков, что в каждом бине имеется разное количество точек (или нет точек в некоторых бинах), я не могу создать массив numpy или использовать np.median, и вместо этого я должен выполнить тяжелую работу в цикле for:
indices=np.array([0,1,1,1,3,1,1,0,0,0,3])
data = np.arange(len(indices))
Данные в бин-массивах
[data[indices == i] for i in range(length)]
[array([0, 7, 8, 9]),
array([1, 2, 3, 5, 6]),
array([], dtype=int64),
array([ 4, 10])]
Но я не могу взять медиану из списка массивов.Вместо этого я могу сделать
[np.median(data[indices == i]) for i in range(length)]
и получить
[7.5, 3.0, nan, 7.0]
Но цикл for довольно медленный.(У меня есть несколько миллионов точек данных и десятки или сотни тысяч бинов в моих реальных данных.)
Есть ли способ сделать это, чтобы избежать сильной зависимости для циклов (или даже избавиться от циклов for)в целом)?