Если вы используете библиотеку jQuery, рассмотрите возможность использования http://api.jquery.com/jQuery.each/
Из документации:
jQuery.each( collection, callback(indexInArray, valueOfElement) )
Возвраты: Объект
Описание: Общая функция итератора, которая может использоваться для беспрепятственной итерации над объектами и массивами. Массивы и подобные массиву объекты с свойством length (например, объект аргументов функции) повторяются с помощью числового индекса от 0 до длины-1. Другие объекты повторяются через их именованные свойства.
Функция
blockquote>$.each()
не совпадает с$(selector).each()
, которая используется исключительно для итерации над объектом jQuery. Функция$.each()
может использоваться для итерации по любой коллекции, будь то карта (объект JavaScript) или массив. В случае массива обратный вызов каждый раз передается индексом массива и соответствующим значением массива. (Доступ к этому значению также можно получить через ключевое словоthis
, но Javascript всегда будет помещать значениеthis
в качествеObject
, даже если это простая строка или числовое значение.) Метод возвращает свой первый аргумент, объект который был повторен.
Ну, ты хочешь этого в numpy или в Theano? В случае, когда, как вы заявляете, вы хотели бы сжимать ось 3 A против оси 2 из B, оба являются простыми:
import numpy as np
a = np.arange(3 * 4 * 5).reshape(3, 4, 5).astype('float32')
b = np.arange(3 * 5).reshape(3, 5).astype('float32')
result = a.dot(b.T)
в Theano это записывается как
import theano.tensor as T
A = T.ftensor3()
B = T.fmatrix()
out = A.dot(B.T)
out.eval({A: a, B: b})
, однако выход имеет форму (3, 4, 3). Поскольку вам кажется, что вы хотите получить форму (3, 4), альтернатива numpy использует einsum, например
einsum_out = np.einsum('ijk, ik -> ij', a, b)
Однако eanum не существует в Theano. Таким образом, конкретный случай здесь можно эмулировать следующим образом
out = (a * b[:, np.newaxis]).sum(2)
, который также может быть записан в Theano
out = (A * B.dimshuffle(0, 'x', 1)).sum(2)
out.eval({A: a, B: b})
В этом конкретном случае einsum
, вероятно, легче понять, чем tensordot
. Например:
c = np.einsum('ijk,ik->ij', a, b)
Я немного упрощу объяснение, чтобы сделать вещи более понятными. У нас есть два входных массива (разделенных запятой), и это дает наш выходной массив (справа от ->
).
a
имеет форму 3, 4, 5
, и мы ссылайтесь на него как ijk
b
имеет форму 3, 5
(ik
) c
имел форму 3, 4
(ij
]) Кажется немного магическим, верно? Давайте немного сломаем это.
->
, представляют собой оси, которые будут суммированы. Это также делает dot
. 3, 4
, поэтому мы устраняем k
c
должен be ij
b
как ik
. В качестве полного примера:
import numpy as np
a = np.random.random((3, 4, 5))
b = np.random.random((3, 5))
# Looping through things
c1 = []
for i in range(3):
c1.append(a[i].dot(b[i]))
c1 = np.array(c1)
# Using einsum instead
c2 = np.einsum('ijk,ik->ij', a, b)
assert np.allclose(c1, c2)
Вы можете сделать это с помощью tensordot
. Я добавлю пример этого, как только у меня будет немного больше времени. (Конечно, если кто-то еще хотел бы добавить пример tensordot
в качестве еще одного ответа, не стесняйтесь!) [/ G11]