Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在多维numpy数组中迭代向量_Python_Numpy - Fatal编程技术网

Python 在多维numpy数组中迭代向量

Python 在多维numpy数组中迭代向量,python,numpy,Python,Numpy,我有一个3xnxmnumpy数组a,我想迭代最后两个轴:a[:,x,y]。不雅的做法是: import numpy as np a = np.arange(60).reshape((3,4,5)) M = np. array([[1,0,0], [0,0,0], [0,0,-1]]) for x in arange(a.shape[1]): for y in arange(a.shape[2]): a[:,x,

我有一个3xnxmnumpy数组a,我想迭代最后两个轴:a[:,x,y]。不雅的做法是:

import numpy as np
a = np.arange(60).reshape((3,4,5))
M = np. array([[1,0,0],
               [0,0,0],
               [0,0,-1]])

for x in arange(a.shape[1]):
    for y in arange(a.shape[2]):
        a[:,x,y] = M.dot(a[:,x,y])
这可以用nditer完成吗?其目的是对每个条目执行矩阵乘法,例如a[:,x,y]=M[:,:,x,y].dot(a[:,x,y])。另一种MATLAB风格的方法是重塑as(3,N*M)和MAS(3,3*N*M)并采用点积,但这往往会占用大量内存

for x in np.arange(a.shape[1]):
    for y in np.arange(a.shape[2]):
        a[:,x,y] = M.dot(a[:,x,y])
相当于

a = np.dot(M,a.swapaxes(0,1))


说明:

对于多维数组,
np.dot(M,a)

a
具有形状(3,4,5),但我们希望在轴上求和形状3。由于第二个到最后一个轴将被求和,我们需要
a.swapaxis(0,1)
——它具有形状(4,3,5)——将3移动到第二个到最后一个轴


M
具有形状(3,3),
a.swapaxis(0,1)
具有形状(4,3,5)。移除
M
的最后一个轴和
a.swapaxis(0,1)
的第二个到最后一个轴,会得到(3,)和(4,5),因此
np.dot
返回的结果是一个形状数组(3,4,5)--这正是我们想要的。

在玩弄形状的同时,可能会让你想要完成的事情更加清楚,处理此类问题而不必考虑太多的最简单方法是:

此外,它通常还附带绩效奖金:

In [17]: a = np.random.randint(256, size=(3, 1000, 2000))

In [18]: %timeit np.dot(M, a.swapaxes(0,1))
10 loops, best of 3: 116 ms per loop

In [19]: %timeit np.einsum('ij, jkl', M, a)
10 loops, best of 3: 60.7 ms per loop

EDIT
einsum
是非常强大的伏都教。您也可以按照OP在下面评论中的要求执行以下操作:

>>> a = np.arange(60).reshape((3,4,5))
>>> M = np.array([[1,0,0], [0,0,0], [0,0,-1]])
>>> M = M.reshape((3,3,1,1)).repeat(4,axis=2).repeat(5,axis=3)
>>> np.einsum('ijkl,jkl->ikl', M, b)
array([[[  0,   1,   2,   3,   4],
        [  5,   6,   7,   8,   9],
        [ 10,  11,  12,  13,  14],
        [ 15,  16,  17,  18,  19]],

       [[  0,   0,   0,   0,   0],
        [  0,   0,   0,   0,   0],
        [  0,   0,   0,   0,   0],
        [  0,   0,   0,   0,   0]],

       [[-40, -41, -42, -43, -44],
        [-45, -46, -47, -48, -49],
        [-50, -51, -52, -53, -54],
        [-55, -56, -57, -58, -59]]])

谢谢有没有办法在einsum中包含元素级乘法?例如,我有一个大小为3xMxN的向量数组(如上所述),我想用大小为3xMxN的张量M对每个向量执行矩阵旋转。a=arange(60)。重塑((3,4,5))M=arange中的数组([1,0,0],[0,0,0],[0,0,-1]))M=M。重塑((3,3,1,1))。重复(4,轴=2)。对arange中的x重复(5,轴=3)(a.shape[1]):对arange中的y(a.shape[2]):a[:,x,y]=M[,:,:,x,y]。点(a[:,x,y])正确的einsum方法是什么?我有:b=einsum('ijkl,jxy',M,a)c=b[:,0,0,:,:,:]@emarti我编辑了我的答案,以在评论中涵盖你的问题。
In [17]: a = np.random.randint(256, size=(3, 1000, 2000))

In [18]: %timeit np.dot(M, a.swapaxes(0,1))
10 loops, best of 3: 116 ms per loop

In [19]: %timeit np.einsum('ij, jkl', M, a)
10 loops, best of 3: 60.7 ms per loop
>>> a = np.arange(60).reshape((3,4,5))
>>> M = np.array([[1,0,0], [0,0,0], [0,0,-1]])
>>> M = M.reshape((3,3,1,1)).repeat(4,axis=2).repeat(5,axis=3)
>>> np.einsum('ijkl,jkl->ikl', M, b)
array([[[  0,   1,   2,   3,   4],
        [  5,   6,   7,   8,   9],
        [ 10,  11,  12,  13,  14],
        [ 15,  16,  17,  18,  19]],

       [[  0,   0,   0,   0,   0],
        [  0,   0,   0,   0,   0],
        [  0,   0,   0,   0,   0],
        [  0,   0,   0,   0,   0]],

       [[-40, -41, -42, -43, -44],
        [-45, -46, -47, -48, -49],
        [-50, -51, -52, -53, -54],
        [-55, -56, -57, -58, -59]]])