Повышение производительности объединения / добавления

#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. ваша проблема в том, что вы вызываете это миллионы раз: вместо этого вы должны попытаться векторизовать это.