开发者

numpy tensordot related issue

开发者 https://www.devze.com 2023-02-15 05:49 出处:网络
I have a specific issue with multiplying matrices in numpy. Here is an example: P=np.ar开发者_开发技巧ange(30).reshape((-1,3))

I have a specific issue with multiplying matrices in numpy. Here is an example:

P=np.ar开发者_开发技巧ange(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]])

I want to multiply each row by its transpose in order to obtain a 3x3 matrix for each row, for example for the first row:

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

and store the result in a 3-d matrix M:

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

I think there might be a way to do this without looping, maybe with tensor-dot, but cannot find it.

Does someone have an idea?


It's just simple like this:

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]])


Since I like stride_tricks, that's what I'd use. I'm sure there are other ways.

Change the stride and shape of the array so that you expand it into 3D. You could easily do the same thing with the "transposed" version of P, but here I just reshape it and let the broadcasting rules stretch it into the other dimension.

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))

I'm going to add a reference to this post because it is a nice detailed explanation of stride_tricks.as_strided.


This partially solves the problem using 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 contains all the products you want (and more), it's just a question of extracting them.

0

精彩评论

暂无评论...
验证码 换一张
取 消