Ненужное элементное произведение 3d-массива

У меня есть два 3D-массива A и B с формой (N, 2, 2), которые я хотел бы умножить по элементам в соответствии с осью N с матричным произведением на каждой из матриц 2×2. С реализацией цикла это выглядит

C[i] = dot(A[i], B[i]) 

Есть ли способ сделать это без использования цикла? Я посмотрел на тендердот, но не смог заставить его работать. Я думаю, что мне может понадобиться что-то вроде tensordot(a, b, axes=([1,2], [2,1])) но это дает мне матрицу NxN.

2 Solutions collect form web for “Ненужное элементное произведение 3d-массива”

Кажется, вы делаете матричные умножения для каждого среза вдоль первой оси. Для этого вы можете использовать np.einsum например,

 np.einsum('ijk,ikl->ijl',A,B) 

Проверка времени выполнения и проверка результатов –

 In [179]: N = 10000 ...: A = np.random.rand(N,2,2) ...: B = np.random.rand(N,2,2) ...: ...: def einsum_based(A,B): ...: return np.einsum('ijk,ikl->ijl',A,B) ...: ...: def forloop(A,B): ...: N = A.shape[0] ...: C = np.zeros((N,2,2)) ...: for i in range(N): ...: C[i] = np.dot(A[i], B[i]) ...: return C ...: In [180]: np.allclose(einsum_based(A,B),forloop(A,B)) Out[180]: True In [181]: %timeit forloop(A,B) 10 loops, best of 3: 54.9 ms per loop In [182]: %timeit einsum_based(A,B) 100 loops, best of 3: 5.92 ms per loop 

Вам просто нужно выполнить операцию над первым измерением ваших тензоров, который помечен как 0 :

 c = tensordot(a, b, axes=(0,0)) 

Это будет работать по вашему желанию. Также вам не нужен список осей, потому что это просто одно измерение, которое вы выполняете. С axes([1,2],[2,1]) вы перекрещиваетесь с 2-м и 3-м измерениями. Если вы пишете его в индексной нотации (соглашение суммирования Эйнштейна), это соответствует c[i,j] = a[i,k,l]*b[j,k,l] , таким образом, вы сокращаете индексы, которые вы хотите держать.

EDIT: Хорошо, проблема в том, что тензорное произведение двух 3d-объектов является объектом 6d. Поскольку сокращения связаны с парами индексов, вы не сможете получить 3d-объект с помощью операции tensordot . Трюк состоит в том, чтобы разделить ваш расчет на две части: сначала вы делаете tensordot по индексу для выполнения операции с матрицей, а затем вы берете диагональ тензора, чтобы уменьшить ваш 4d-объект до 3d. В одной команде:

 d = np.diagonal(np.tensordot(a,b,axes=()), axis1=0, axis2=2) 

В тензорной нотации d[i,j,k] = c[i,j,i,k] = a[i,j,l]*b[i,l,k] .

  • Почему numpy.linalg.solve () предлагает более точные инверсии матрицы, чем numpy.linalg.inv ()?
  • Создание симметричных матриц в Numpy
  • Как найти линейно независимые строки из матрицы
  • Как быстро создать массив из матриц N 3x3 из 9 массивов размера N?
  • 2d массив списков в python
  • Опасность смешивания матрицы и матрицы
  • Как сделать матрицу массивов в numpy?
  • Matplotlib 1.3.1: plot (matrix ("1,2,3")) -> RuntimeError: превышена максимальная глубина рекурсии
  • Python - лучший язык программирования в мире.