Самый эффективный способ перебора большого вектора?

#python #numpy

#python #numpy

Вопрос:

У меня есть входной ndarray, pointsCount , с формой (4000000, 1). У меня есть другой ndarray, clusters , с формой (2,1). Затем я хочу выполнить следующее:

 distances = np.zeros((pointsCount, n_clusters))
for x in range(len(trainPoints)):
    for c in range(len(clusters)):
        distances[x,c] = (trainPoints[x]-clusters[c]).T@(trainPoints[x]-clusters[c])
 

Однако для завершения этого требуется время. То же самое верно и для понимания списка distances = np.array([(x-cluster).T@(x-cluster) for x in trainPoints for cluster in clusters]).reshape((4000000, 2)) .

Как я могу выполнить это быстрее, используя numpy?

Комментарии:

1.docs.scipy.org/doc/scipy/reference/spatial.distance.html?

2. Нет, это не обязательно должен быть именно этот случай. Я спрашиваю об общем случае, когда вы будете выполнять математические выражения для каждой итерации 🙂

3. Общий ответ — «векторизировать его», что зависит от ваших операций

4. Вы проверили результаты, это то, что вы ожидали? Я имею в виду, что вы, по сути, возводите результат (pointsCount - clusters) в квадрат, и, следовательно, вам не нужно .T (транспонировать) или @ , если на то пошло. Если это так, то я могу написать более быстрый ответ.

5. @SayandipDutta Результаты соответствуют ожидаемым, и я осознаю тот факт, что я могу удалить .T , но я решил этого не делать, потому что это лучше напоминает матричную алгебру :))

Ответ №1:

Все, что вам нужно сделать, это транспонировать clusters . Например, учитывая начальные массивы:

 >>> pointsCount    # I have considered 4 instead of 4 mil
array([[2],
       [4],
       [7],
       [6]])
>>> clusters
array([[2],
       [3]])
# Your code:
>>> np.array([(x-cluster).T@(x-cluster) for x in pointsCount for cluster in clusters]).reshape((4, 2))
array([[ 0,  1],
       [ 4,  1],
       [25, 16],
       [16,  9]])

# Faster code:
>>> (pointsCount - clusters.T)**2 
array([[ 0,  1],
       [ 4,  1],
       [25, 16],
       [16,  9]], dtype=int32)
 

Возможно, вы захотите взглянуть на NumPy Broadcasting

Комментарии:

1. Wuttttt, черт возьми, это быстрее! На очень большую величину!