Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.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在3D网格上进行点产品广播_Python_Numpy_3d_Array Broadcasting - Fatal编程技术网

Python 使用numpy在3D网格上进行点产品广播

Python 使用numpy在3D网格上进行点产品广播,python,numpy,3d,array-broadcasting,Python,Numpy,3d,Array Broadcasting,我想了解如何在10x10 3D网格上进行系统的点产品操作。我制定了以下阵列: A.shape=(5,5,10,10,10) b.shape=(5,10,10,10) 我想获得一个如下所示的数组 c.shape=(5,10,10,10) 到目前为止,我是通过以下代码获得的 c=np.sum(A*b,axis=1) 然而,我相信,我应该能够用np.dot或np.tensordot获得相同的结果。我尽了最大的努力,但无法取得同样的结果。 这样做将有助于我了解np.tensordot的工作原理,因

我想了解如何在10x10 3D网格上进行系统的点产品操作。我制定了以下阵列:

A.shape=(5,5,10,10,10)
b.shape=(5,10,10,10)
我想获得一个如下所示的数组

c.shape=(5,10,10,10)
到目前为止,我是通过以下代码获得的

c=np.sum(A*b,axis=1)
然而,我相信,我应该能够用np.dot或np.tensordot获得相同的结果。我尽了最大的努力,但无法取得同样的结果。
这样做将有助于我了解np.tensordot的工作原理,因为我还需要在以后的工作中使用np.tensorsolve。

我们需要保持最后四个轴对齐,并在输出中保留这些轴,但第二个轴(轴=1)除外,第二个轴将被求和缩减。对于这种情况,除了
np.matmul
之外,还有一条路要走。有了
np.einsum
,就更容易/直观了-

c = np.einsum('ijklm,jklm->iklm',A,b)

如果“点”尺寸在末端,
matmul
将起作用

比较3种方法:

In [252]: A=np.arange(5*5*10*10*10).reshape((5,5,10,10,10))
In [253]: B=np.arange(5*10*10*10).reshape((5,10,10,10))

In [254]: C=np.sum(A*B, axis=1)
In [255]: D=np.einsum('ijklm,jklm->iklm',A,B)
In [256]: E = (A.transpose(2,3,4,0,1)@B.transpose(1,2,3,0)[...,None])[...,0].transpose(3,0,1,2)
所有的转置使数组变成
(…..,5,5)
(…,5,1)

tensordot
对数组进行重塑和转置,这样它就可以进行简单的2d
dot
——然后再转换回来。最后3个维度实际上是一个1000维

In [262]: np.tensordot(A,B,(1,0)).shape
Out[262]: (5, 10, 10, 10, 10, 10, 10)
In [263]: timeit np.tensordot(A,B,(1,0)).shape
74 ms ± 70.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
结果要大得多——一种非求和维度上的外积。结果就在那里,被掩埋成一条多维的对角线

tensordot有效地:

In [264]: X=(B.reshape(5,1000).T).dot(A.reshape(5,5,1000))
In [265]: X.shape
Out[265]: (1000, 5, 1000)
In [266]: timeit X=(B.reshape(5,1000).T).dot(A.reshape(5,5,1000))
78.9 ms ± 82.6 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

非常感谢您的回答!我猜np.tensordot不适合这样的问题?如果我将数组重新格式化为如下所示呢
A.shape=(10,10,10,5,5)
b.shape=(10,10,10,5)
c.shape=(10,10,10,5)
@Michele将取决于在这种情况下如何获得
c
。简单地说明输出形状并不能提供完整的信息。此外,为了了解tensordot是如何工作的,请遵循以下步骤-想法是对3D系统的每个坐标执行点积a*b(a=(5x5),b=(5x1))。A和b在不同的坐标中都不同。@Michele所以,我猜:
np.einsum('ijklm,ijkm->ijkl',A,b)
。但是,
tensordot
将无法工作,因为需要再次进行轴对齐。
tensordot
有效地对未求和的尺寸进行外积,在您的情况下产生
(5,10,10,10,10,10)。
。所需的值作为某种对角线嵌入其中,但它计算的值比您需要的多得多。通过一些轴交换
mutmul
可以执行所需的计算,因为它的外部尺寸
与骑乘相关
。但是<代码> EnSuth是最容易使用的。如果你的问题已经得到回答,请考虑接受其中的一个。更多信息-。非常感谢您的回答,比较对于评估这些方法的速度非常有用!然而,正如您在开始时提到的,我选择重新表述我的问题,将“点”维度移动到数组的末尾,这使一切变得更加容易。
In [264]: X=(B.reshape(5,1000).T).dot(A.reshape(5,5,1000))
In [265]: X.shape
Out[265]: (1000, 5, 1000)
In [266]: timeit X=(B.reshape(5,1000).T).dot(A.reshape(5,5,1000))
78.9 ms ± 82.6 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)