Это не ответ сам по себе, но, вероятно, он будет быстрее из-за использования numpy, а не цикла python for.
Сначала вы хотите выполнить binning :
>> bins = np.digitize(t, z) - 1 # minus 1 just to align our shapes
array([5, 5, 3, 1, 0, 2, 0, 5, 6, 4, 2, 0, 4, 5, 2])
Это говорит вам, в каком бине находится каждое из ваших значений. Затем определите ваши шаблоны в следующем порядке:
>> patterns = np.array([
[0,0,0,0,0],
[0,0,0,0,1],
[0,0,0,1,0],
[0,0,0,1,1],
[0,0,1,0,0],
[0,0,1,0,1],
[0,0,1,1,0],
])
Теперь для некоторой непонятной магии вместо добавления / расширения создайте массив, полный нулей (это должно быть почти всегда быстрее). Этот массив будет иметь форму (len(t), len(z)-1)
. Используя этот SO-ответ , мы также сделаем горячее кодирование:
>> inds = np.zeros((len(t), len(z)-1))
>> inds[np.arange(len(t)), bins] = 1
>> inds
array([[0., 0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 1., 0.],
[0., 0., 0., 1., 0., 0., 0.],
.....,
[0., 0., 0., 0., 0., 1., 0.],
[0., 0., 1., 0., 0., 0., 0.]])
Наконец, все, что нам нужно, это умножение матриц
>> inds @ patterns
array([[0., 0., 1., 0., 1.],
[0., 0., 1., 0., 1.],
[0., 0., 0., 1., 1.],
....
[0., 0., 1., 0., 1.],
[0., 0., 0., 1., 0.]])
Я не проводил качественный временной тест, но из моих небольших экспериментов вот мои результаты:
Ваш цикл: 17,7 мкс ± 160 нс на цикл (среднее ± стандартное отклонение из 7 циклов, 100000 циклов в каждом)
Моя реализация: 8,49 мкс ± 125 нс на цикл (среднее ± стандартное отклонение из 7 циклов, 100000 циклов каждый)
Что может или не может хорошо масштабироваться для больших наборов данных. Надеюсь, это поможет:)
Редактировать: После ответа Александра Лопатина Мне было интересно увидеть, что мой метод был значительно медленнее. После дальнейшего изучения один из выводов, к которым я пришел, заключался в том, что функции numpy
имеют некоторые существенные накладные расходы, что является недешевой ценой, которую приходится платить за несколько значений t
. Для больших списков незначительные накладные расходы незначительны, но прирост производительности не равен:
timings = {
10: [7.79, 24.1, 21.7],
16: [10.7, 29.9, 22.9],
24: [14.6, 40.5, 23.4],
33: [19.1, 48.6, 23.4],
38: [21.9, 55.9, 23.9],
47: [26.7, 66.2, 24.1],
61: [33, 79.5, 24.7],
75: [40.8, 92.6, 25.8],
89: [47.6, 108, 26.2],
118: [60.1, 136, 27.4],
236: [118, 264, 33.1],
472: [236, 495, 40.9],
1000: [657, 922, 52],
10000: [6530, 9090, 329]
}
Zoom: