проблема с NumPy Tensordot - PullRequest
       20

проблема с NumPy Tensordot

2 голосов
/ 08 марта 2011

У меня есть конкретная проблема с умножением матриц в numpy.Вот пример:

P=np.arange(30).reshape((-1,3))
array([[ 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]])

Я хочу умножить каждую строку на ее транспонирование, чтобы получить матрицу 3x3 для каждой строки, например, для первой строки:

P[0]*P[0][:,np.newaxis]
array([[0, 0, 0],
   [0, 1, 2],
   [0, 2, 4]])

и сохранить результат в 3-й матрице M:

M=np.zeros((10,3,3))
for i in range(10):
    M[i] = P[i]*P[i][:,np.newaxis]

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

У кого-то есть идея?

Ответы [ 3 ]

3 голосов
/ 08 марта 2011

Все просто так:

In []: P= arange(30).reshape(-1, 3)
In []: P[:, :, None]* P[:, None, :]
Out[]:
array([[[  0,   0,   0],
        [  0,   1,   2],
        [  0,   2,   4]],
       [[  9,  12,  15],
        [ 12,  16,  20],
        [ 15,  20,  25]],
       [[ 36,  42,  48],
        [ 42,  49,  56],
        [ 48,  56,  64]],
       #...   
       [[729, 756, 783],
        [756, 784, 812],
        [783, 812, 841]]])    
In []: P[1]* P[1][:, None]
Out[]:
array([[ 9, 12, 15],
       [12, 16, 20],
       [15, 20, 25]])
1 голос
/ 08 марта 2011

Так как я люблю stride_tricks, это то, что я бы использовал.Я уверен, что есть и другие способы.

Измените шаг и форму массива так, чтобы вы расширили его в 3D.Вы можете легко сделать то же самое с «транспонированной» версией P, но здесь я просто изменяю ее и позволяю правилам вещания растянуть ее в другое измерение.

P=np.arange(30).reshape((-1,3))
astd = numpy.lib.stride_tricks.as_strided
its = P.itemsize
M = astd(P,(10,3,3),(its*3,its,0))*P.reshape((10,1,3))

Я собираюсь добавитьссылка на этот пост , потому что это хорошее подробное объяснение stride_tricks.as_strided.

0 голосов
/ 08 марта 2011

Это частично решает проблему, используя tensordot(),

from numpy import arange,tensordot

P = arange(30).reshape((-1,3))

i = 3

T = tensordot(P,P,0)[:,:,i,:]

print T[i]
print tensordot(P[i],P[i],0)

T содержит все продукты, которые вы хотите (и даже больше), это просто вопрос их извлечения.

...