Изменение выходного массива numpy функции на месте - PullRequest
6 голосов
/ 23 сентября 2011

Я пытаюсь написать функцию, которая выполняет математическую операцию над массивом и возвращает результат. Упрощенный пример может быть:

def original_func(A):
    return A[1:] + A[:-1]

Для ускорения и во избежание выделения нового выходного массива для каждого вызова функции я хотел бы иметь выходной массив в качестве аргумента и изменить его на месте:

def inplace_func(A, out):
    out[:] = A[1:] + A[:-1]

Однако при вызове этих двух функций следующим образом,

A = numpy.random.rand(1000,1000)
out = numpy.empty((999,1000))

C = original_func(A)

inplace_func(A, out)

кажется, что исходная функция в два раза быстрее , чем функция на месте. Как это можно объяснить? Разве функция на месте не должна быть быстрее, поскольку ей не нужно выделять память?

Ответы [ 3 ]

12 голосов
/ 24 сентября 2011

Если вы хотите выполнить операцию на месте, выполните команду

def inplace_func(A, out):
    np.add(A[1:], A[:-1], out)

. Это не создает временных файлов (что делает A[1:] + A[:-1]).

Все двоичные операции Numpy имеют соответствующиефункции, проверьте список здесь: http://docs.scipy.org/doc/numpy/reference/ufuncs.html#available-ufuncs

5 голосов
/ 23 сентября 2011

I думаю , что ответ следующий:

В обоих случаях вы вычисляете A[1:] + A[:-1], и в обоих случаях вы фактически создаете промежуточную матрицу.

Однако во втором случае вы явно копируете весь большой вновь выделенный массив в зарезервированную память.Копирование такого массива занимает примерно то же время, что и исходная операция, поэтому вы фактически удваиваете время.

Подводя итог, в первом случае вы делаете:

compute A[1:] + A[:-1] (~10ms)

Во втором случае вы делаете

compute A[1:] + A[:-1] (~10ms)
copy the result into out (~10ms)
0 голосов
/ 23 сентября 2011

Я согласен с объяснением Оливера.Если вы хотите выполнить операцию на месте, вы должны зациклить свой массив вручную.Это будет намного медленнее, но если вам нужна скорость, вы можете прибегнуть к Cython, который дает вам скорость чистой реализации на C.

...