Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.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_Multidimensional Array_Linear Algebra_Numpy Ndarray - Fatal编程技术网

Python 如何在numpy中沿特定维度获取点积?

Python 如何在numpy中沿特定维度获取点积?,python,numpy,multidimensional-array,linear-algebra,numpy-ndarray,Python,Numpy,Multidimensional Array,Linear Algebra,Numpy Ndarray,我有两个数组。一个是n乘以p,另一个是d乘以p乘以r。我希望我的输出是d乘以n乘以r,这在我构造下面的张量B时很容易实现。但是,我希望在不使用循环的情况下执行此操作 import numpy X = numpy.array([[1,2,3],[3,4,5],[5,6,7],[7,8,9]]) # n x p betas = numpy.array([[[1,2],[1,2],[1,2]], [[5,6],[5,6],[5,6]]]) # d x p x r print X.shape pri

我有两个数组。一个是n乘以p,另一个是d乘以p乘以r。我希望我的输出是d乘以n乘以r,这在我构造下面的张量B时很容易实现。但是,我希望在不使用循环的情况下执行此操作

import numpy

X = numpy.array([[1,2,3],[3,4,5],[5,6,7],[7,8,9]]) # n x p
betas = numpy.array([[[1,2],[1,2],[1,2]], [[5,6],[5,6],[5,6]]]) # d x p x r

print X.shape
print betas.shape

B = numpy.zeros((betas.shape[0],X.shape[0],betas.shape[2]))
print B.shape

for i in range(B.shape[0]):
    B[i,:,:] = numpy.dot(X, betas[i])

print "B",B

C = numpy.tensordot(X, betas, axes=([1],[0]))
print C.shape
我试过各种方法让C和B匹配,但到目前为止我都没有成功。有没有一种方法不需要调用重塑?我们可以使用,然后需要置换轴-

B = np.tensordot(betas, X, axes=(1,1)).swapaxes(1,2)
# Or np.tensordot(X, betas, axes=(1,1)).swapaxes(0,1)
.

我们可以使用,然后需要排列轴-

B = np.tensordot(betas, X, axes=(1,1)).swapaxes(1,2)
# Or np.tensordot(X, betas, axes=(1,1)).swapaxes(0,1)
.

由于点规则是“A的最后一个,B的第二个到最后一个”,您可以执行X.dotbetas并获得一个n、d、r数组,该数组在共享的p维度上求和。然后你只需要一个转置就可以得到d,n,r

In [200]: X.dot(betas).transpose(1,0,2)
Out[200]: 
array([[[  6,  12],
        [ 12,  24],
        [ 18,  36],
        [ 24,  48]],

       [[ 30,  36],
        [ 60,  72],
        [ 90, 108],
        [120, 144]]])
我们也可以直接从尺寸规格中编写einsum版本:

np.einsum('np,dpr->dnr', X,betas)
matmul也是,这在最后两个轴上都有点,而d则在骑行时出现

X@betas
如果任一参数为N-D,N>2,则将其视为 位于最后两个索引中的矩阵,并相应地广播。 由于点规则是“A的最后一个,B的第二个到最后一个”,您可以执行X.dotbetas并获得一个n、d、r数组,该数组在共享p维度上求和。然后你只需要一个转置就可以得到d,n,r

In [200]: X.dot(betas).transpose(1,0,2)
Out[200]: 
array([[[  6,  12],
        [ 12,  24],
        [ 18,  36],
        [ 24,  48]],

       [[ 30,  36],
        [ 60,  72],
        [ 90, 108],
        [120, 144]]])
我们也可以直接从尺寸规格中编写einsum版本:

np.einsum('np,dpr->dnr', X,betas)
matmul也是,这在最后两个轴上都有点,而d则在骑行时出现

X@betas
如果任一参数为N-D,N>2,则将其视为 位于最后两个索引中的矩阵,并相应地广播。
这里是另一种使用的方法,它还可以根据您的请求返回视图,最重要的是比这种方法快4倍多,特别是对于小型阵列。但是,对于相当大的阵列,它比普通阵列快得多。见下面的计时

In [108]: X.shape
Out[108]: (4, 3)

In [109]: betas.shape
Out[109]: (2, 3, 2)

# use `np.dot` and roll the second axis to first position
In [110]: dot_prod = np.rollaxis(np.dot(X, betas), 1)

In [111]: dot_prod.shape
Out[111]: (2, 4, 2)

# @Divakar's approach
In [113]: B = np.tensordot(betas, X, axes=(1,1)).swapaxes(1,2)

# sanity check :)
In [115]: np.all(np.equal(dot_prod, B))
Out[115]: True
现在,两种方法的性能:

对于小型阵列,其速度比 对于相当大的阵列,比
这里是另一种使用的方法,它还可以根据您的请求返回视图,最重要的是比这种方法快4倍多,特别是对于小型阵列。但是,对于相当大的阵列,它比普通阵列快得多。见下面的计时

In [108]: X.shape
Out[108]: (4, 3)

In [109]: betas.shape
Out[109]: (2, 3, 2)

# use `np.dot` and roll the second axis to first position
In [110]: dot_prod = np.rollaxis(np.dot(X, betas), 1)

In [111]: dot_prod.shape
Out[111]: (2, 4, 2)

# @Divakar's approach
In [113]: B = np.tensordot(betas, X, axes=(1,1)).swapaxes(1,2)

# sanity check :)
In [115]: np.all(np.equal(dot_prod, B))
Out[115]: True
现在,两种方法的性能:

对于小型阵列,其速度比 对于相当大的阵列,比
它返回一个视图,而不是一个新数组!太好了。对于较大的阵列,tensordot是超高速的。。但对于小型阵列,np.dot比tensordot快4倍。。不知道为什么会这样case@kmario23有关讨论,请参见此处,它将返回一个视图,而不是一个新数组!太好了。对于较大的阵列,tensordot是超高速的。。但对于小型阵列,np.dot比tensordot快4倍。。不知道为什么会这样case@kmario23有关讨论,请参见此处-参见我的时间安排。。np.dot对于小型阵列比tensordot更快,但对于大型阵列则相反。不知道为什么。有什么想法吗?Tensordot使用圆点,只是按摩输入和结果以适应重塑和转置。参见我的计时。。np.dot对于小型阵列比tensordot更快,但对于大型阵列则相反。不知道为什么。有什么想法吗?Tensordot使用点,只是通过调整输入和结果来适应重塑和转置。一旦使用Tensordot完成初始设置开销,它应该比np.dot版本-np.rollaxisnp.dotX,betas,1更快。所以,它不必是相当大的数组。因此,hpaulj认为np.tensordot使用np.dot。我想我必须检查一下代码才能很好地掌握发生了什么。。。我真的希望NumPy开发者尽早开始实施对GPU的支持一旦使用tensordot克服了初始设置开销,它应该比np.dot版本更快—np.rollaxisnp.dotX,betas,1。所以,它不必是相当大的数组。因此,hpaulj认为np.tensordot使用np.dot。我想我必须检查一下代码才能很好地掌握发生了什么。。。我真的希望NumPy开发者尽早开始实施对GPU的支持