在NumPy中将按元素乘法和矩阵乘法与多维数组相结合 [英] Combining element-wise and matrix multiplication with multi-dimensional arrays in NumPy

查看:92
本文介绍了在NumPy中将按元素乘法和矩阵乘法与多维数组相结合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个多维NumPy数组,分别为AB,分别为A.shape = (K, d, N)B.shape = (K, N, d).我想在轴0(K)上执行逐个元素的操作,该操作是在轴1和2(d, NN, d)上进行矩阵乘法.因此,结果应为带有C.shape = (K, d, d)的多维数组C,即C[k] = np.dot(A[k], B[k]).天真的实现看起来像这样:

I have two multidimensional NumPy arrays, A and B, with A.shape = (K, d, N) and B.shape = (K, N, d). I would like to perform an element-wise operation over axis 0 (K), with that operation being matrix multiplication over axes 1 and 2 (d, N and N, d). So the result should be a multidimensional array C with C.shape = (K, d, d), so that C[k] = np.dot(A[k], B[k]). A naive implementation would look like this:

C = np.vstack([np.dot(A[k], B[k])[np.newaxis, :, :] for k in xrange(K)])

,但是此实现是 slow .稍微快一点的方法是这样的:

but this implementation is slow. A slightly faster approach looks like this:

C = np.dot(A, B)[:, :, 0, :]

在多维数组上使用默认行为np.dot,为我提供了形状为(K, d, K, d)的数组.但是,此方法计算所需的答案K次(沿轴2的每个条目都相同).渐近地,它会比第一种方法慢,但开销却少得多.我也知道以下方法:

which uses the default behaviour of np.dot on multidimensional arrays, giving me an array with shape (K, d, K, d). However, this approach computes the required answer K times (each of the entries along axis 2 are the same). Asymptotically it will be slower than the first approach, but the overhead is much less. I am also aware of the following approach:

from numpy.core.umath_tests import matrix_multiply
C = matrix_multiply(A, B)

但是我不能保证此功能将可用.因此,我的问题是,NumPy是否提供有效执行此操作的标准方法?通常,适用于多维数组的答案将是完美的,但仅针对这种情况的答案也将是很好的.

but I am not guaranteed that this function will be available. My question is thus, does NumPy provide a standard way of doing this efficiently? An answer which applies to multidimensional arrays in general would be perfect, but an answer specific to only this case would be great too.

编辑:如@Juh_所指出的,第二种方法是不正确的.正确的版本是:

As pointed out by @Juh_, the second approach is incorrect. The correct version is:

C = np.dot(A, B).diagonal(axis1=0, axis2=2).transpose(2, 0, 1)

,但是增加的开销比第一种方法慢了 ,即使对于小型矩阵也是如此.最后一种方法是在所有大型和大型矩阵的时序测试中都取得长足的成功.我现在正在强烈考虑使用此方法,如果没有更好的解决方案出现,即使那意味着将numpy.core.umath_tests库(用C语言编写)复制到我的项目中.

but the overhead added makes it slower than the first approach, even for small matrices. The last approach is winning by a long shot on all my timing tests, for small and large matrices. I'm now strongly considering using this if no better solution crops up, even if that would mean copying the numpy.core.umath_tests library (written in C) into my project.

推荐答案

可能的解决方案是:

C = np.sum(A[:,:,:,np.newaxis]*B[:,np.newaxis,:,:],axis=2)

但是:

  1. 仅当K比d和N大得多时,它才比vstack方法更快.
  2. 这可能是一些内存问题:在上述解决方案中,分配了KxdxNxd数组(即所有可能的乘积对,求和之前).实际上,由于内存不足,我无法使用大的K,d和N进行测试.

顺便说一句,请注意:

C = np.dot(A, B)[:, :, 0, :]

没有给出正确的结果.之所以被骗,是因为我首先通过将结果与此np.dot命令给出的结果进行比较来检查我的方法.

does not give the correct result. It got me tricked because I first checked my method by comparing the results to those given by this np.dot command.

这篇关于在NumPy中将按元素乘法和矩阵乘法与多维数组相结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆