Как нажимать for-loop до numpy

У меня есть следующий фрагмент кода, который делает именно то, что я хочу (это часть метода кригинга). Но проблема в том, что она идет слишком медленно, и я хочу знать, есть ли какая-либо опция для того, чтобы заставить for-loop до numpy? Если я выталкиваю numpy.sum и использую аргумент оси там, он немного ускоряется, но, видимо, это не узкое место. Любые идеи о том, как я могу нажать на forloop на numpy, чтобы ускорить его, или другие способы ускорить его?)

# n = 2116 print GRZVV.shape # (16309, 2116) print GinvVV.shape # (2117, 2117) VVg = numpy.empty((GRZVV.shape[0])) for k in xrange(GRZVV.shape[0]): GRVV = numpy.empty((n+1, 1)) GRVV[n, 0] = 1 GRVV[:n, 0] = GRZVV[k, :] EVV = numpy.array(GinvVV * GRVV) # GinvVV is numpy.matrix VVg[k] = numpy.sum(EVV[:n, 0] * VV) 

Я разместил размеры матрицы ndarrays n, чтобы очистить некоторые вещи

edit: форма VV равна 2116

2 Solutions collect form web for “Как нажимать for-loop до numpy”

Вы могли бы сделать следующее вместо вашего цикла через k (runtime ~ 3s):

 tmp = np.concatenate((GRZVV, np.ones((16309,1),dtype=np.double)), axis=1) EVV1 = np.dot(GinvVV, tmp.T) #Changed line below based on *askewchan's* recommendation VVg1 = np.sum(np.multiply(EVV1[:n,:],VV[:,np.newaxis]), axis=0) 

В основном вы берете каждую строку GRZVV , добавляя 1 в конец, умножая ее на GinvVV , а затем складывая все элементы в векторе. Если вы не делали «добавление 1», вы могли бы сделать все это без петель как:

 VVg = np.sum(np.dot(GinvVV[:, :-1], GRZVV.T), axis=-1) * VV 

или даже:

 VVg = np.einsum('ij,kj->k', GinvVV[:, :-1], GRZVV) * VV 

Как мы обрабатываем этот дополнительный 1? Ну, результирующий вектор, исходящий от матричного умножения, будет увеличиваться на соответствующее значение в GinvVV[:, -1] , и когда вы добавите их все, значение будет увеличиваться на np.sum(GinvVV[:, -1]) . Поэтому мы можем просто вычислить это один раз и добавить его ко всем элементам вектора возврата:

 VVg = (np.einsum('ij,kj->k', GinvVV[:-1, :-1], GRZVV) + np.sum(GinvVV[:-1, -1])) * VV 

Вышеприведенный код работает, если VV является скаляром. Если это массив формы (n,) , то будет работать следующее:

 GinvVV = np.asarray(GinvVV) VVgbis = (np.einsum('ij,kj->k', GinvVV[:-1, :-1]*VV[:, None], GRZVV) + np.dot(GinvVV[:-1, -1], VV)) 
  • Как разрезать 2D-массив Python? Сбой с: «TypeError: индексы списка должны быть целыми, а не кортежем»
  • Python из памяти большого CSV-файла (numpy)
  • Удалите фон изображения, используя opencv Python
  • Numpy - добавить строку в массив
  • ошибка с чтением float из текстового файла с двумя столбцами в массив в Python
  • Считать ячейки соседних областей
  • заменить значения в массиве
  • Создайте zip-файл непосредственно из массива numpy без файла-посредника
  • Python - лучший язык программирования в мире.