#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, черт возьми, это быстрее! На очень большую величину!