Отображение функций 2D массивов numpy

У меня есть функция foo это берет массив NxM numpy в качестве аргумента и возвращает скалярное значение. У меня есть массив AxNxM numpy data, по которому я хотел бы отобразиться foo дать мне результант numpy массив длины A.

Curently, я делаю это:

result = numpy.array([foo(x) for x in data])

Это работает, но кажется, что я не использую в своих интересах numpy волшебство (и скорость). Существует ли лучший путь?

Я посмотрел на numpy.vectorize, и numpy.apply_along_axis, но никакой работы для функции 2D массивов.

Править: Я делаю повышенную регрессию на 24x24 патчи изображения, таким образом, мой AxNxM - что-то как 1000x24x24. Что я назвал foo выше применяет подобную Хаару функцию к патчу (так, не ужасно в вычислительном отношении интенсивный).

6
задан perimosocordiae 5 May 2010 в 19:54
поделиться

2 ответа

Если NxM велико (скажем, 100), то затраты на итерации над A будут амортизированы практически в ничто.

Скажем, массив имеет размер 1000 X 100 X 100.

Итерация - O(1000), но совокупная стоимость внутренней функции - O(1000 X 100 X 100) - в 10 000 раз медленнее. (Обратите внимание, моя терминология немного корявая, но я знаю, о чем говорю)

Я не уверен, но вы можете попробовать следующее:

result = numpy.empty(data.shape[0])
for i in range(len(data)):
    result[i] = foo(data[i])

Вы сэкономите большое количество памяти на построении списка... но накладные расходы цикла будут больше.

Или вы можете написать параллельную версию цикла и разделить его на несколько процессов. Это может быть намного быстрее, в зависимости от того, насколько интенсивным является foo (поскольку придется компенсировать обработку данных).

2
ответ дан 17 December 2019 в 18:11
поделиться

Вы можете добиться этого, преобразовав свой 3D-массив в 2D-массив с тем же начальным размером и обернув вашу функцию foo функцией, которая работает с 1D-массивами, изменив их форму в соответствии с требованиями foo . Пример (с использованием trace вместо foo ):

from numpy import *

def apply2d_along_first(func2d, arr3d):
    a, n, m = arr3d.shape
    def func1d(arr1d):
        return func2d(arr1d.reshape((n,m)))
    arr2d = arr3d.reshape((a,n*m))
    return apply_along_axis(func1d, -1, arr2d)

A, N, M = 3, 4, 5
data = arange(A*N*M).reshape((A,N,M))

print data
print apply2d_along_first(trace, data)

Вывод:

[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]
  [30 31 32 33 34]
  [35 36 37 38 39]]

 [[40 41 42 43 44]
  [45 46 47 48 49]
  [50 51 52 53 54]
  [55 56 57 58 59]]]
[ 36 116 196]
1
ответ дан 17 December 2019 в 18:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: