#python #performance #numpy #concatenation
#python #Производительность #numpy #конкатенация
Вопрос:
У меня есть массив формы, похожий на (4, 7, 25000)
. Мне нужно выполнить конкатенацию по первому измерению с учетом некоторых фиксированных индексов. Таким образом, конечный массив имеет форму (7, 25000)
.
Я пробовал три подхода, и np.concatenate()
это самый быстрый, но поскольку этот код используется миллионы раз, он все еще медленный.
Есть ли какой-либо способ повысить производительность этой операции?
import time as t
import numpy as np
# Define array and indexes
aa = np.random.uniform(-10, 10, (4, 7, 25000))
weights = np.array([.20, .5, .35, .05])
idxs = (weights * aa.shape[-1]).astype(int)
idxs = (idxs[0], idxs[0] idxs[1], idxs[0] idxs[1] idxs[2])
def f1(aa):
"""Original using np.concatenate()"""
bb = np.concatenate([
aa[0][:, :idxs[0]], aa[1][:, idxs[0]:idxs[1]],
aa[2][:, idxs[1]:idxs[2]], aa[3][:, idxs[2]:]], axis=1)
def f2(aa):
"""Define empty array first. Not faster"""
bb = np.empty((7, 25000))
bb[:, :idxs[0]] = aa[0][:, :idxs[0]]
bb[:, idxs[0]:idxs[1]] = aa[1][:, idxs[0]:idxs[1]]
bb[:, idxs[1]:idxs[2]] = aa[2][:, idxs[1]:idxs[2]]
bb[:, idxs[2]:] = aa[3][:, idxs[2]:]
def f3(aa):
"""Use list appending and transposition. A *lot* slower"""
bb = np.array(
aa[0][:, :idxs[0]].T.tolist()
aa[1][:, idxs[0]:idxs[1]].T.tolist()
aa[2][:, idxs[1]:idxs[1] idxs[2]].T.tolist()
aa[3][:, idxs[2]:].T.tolist()).T
Комментарии:
1. Какое бы решение вы ни получили в итоге, вам следует избегать цепной индексации,
arr[][][]
создающей несколько промежуточных представлений массива и неэффективной.2. Не знал этого, спасибо!
3. Я не думаю, что вы получите лучшую производительность, чем f1. ваша проблема в том, что вы вызываете это миллионы раз: вместо этого вы должны попытаться векторизовать это.