Python 二维数组和长一维数组的乘积,结果应该是三维数组

Python 二维数组和长一维数组的乘积,结果应该是三维数组,python,arrays,numpy,Python,Arrays,Numpy,给定两个阵列,a和b,具有形状;3、3和1000,。如何将它们相乘以得到形状为3、3、1000的数组 a = np.array([[1,2,3],[4,5,6],[7,8,9]]) b = np.linspace(1, 1000, 1000) c = a * b # does not work c = np.outer(a, b) # does not work c = np.outer(a, b[None,] # nope 我试过很多东西,太多了,都记不住了 我也在谷歌上搜索过,但没有结

给定两个阵列,a和b,具有形状;3、3和1000,。如何将它们相乘以得到形状为3、3、1000的数组

a = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = np.linspace(1, 1000, 1000)

c = a * b # does not work
c = np.outer(a, b) # does not work
c = np.outer(a, b[None,] # nope

我试过很多东西,太多了,都记不住了

我也在谷歌上搜索过,但没有结果。

IIUC,使用numpy.einsum:

输出:

c.shape
# (3, 3, 1000)
% python3 script.py
(3, 3, 1000)
[[1. 2. 3.]
 [4. 5. 6.]
 [7. 8. 9.]]
[[1000. 2000. 3000.]
 [4000. 5000. 6000.]
 [7000. 8000. 9000.]]
IIUC,使用numpy.einsum:

输出:

c.shape
# (3, 3, 1000)
% python3 script.py
(3, 3, 1000)
[[1. 2. 3.]
 [4. 5. 6.]
 [7. 8. 9.]]
[[1000. 2000. 3000.]
 [4000. 5000. 6000.]
 [7000. 8000. 9000.]]

您可以通过重塑数组来实现乘法:

M,N = a.shape
B = b.size
c = a.reshape(M,N,1) * b.reshape(1,1,B)
print(c.shape)
print(c[:,:,0])
print(c[:,:,B-1])
输出:

c.shape
# (3, 3, 1000)
% python3 script.py
(3, 3, 1000)
[[1. 2. 3.]
 [4. 5. 6.]
 [7. 8. 9.]]
[[1000. 2000. 3000.]
 [4000. 5000. 6000.]
 [7000. 8000. 9000.]]

您可以通过重塑数组来实现乘法:

M,N = a.shape
B = b.size
c = a.reshape(M,N,1) * b.reshape(1,1,B)
print(c.shape)
print(c[:,:,0])
print(c[:,:,B-1])
输出:

c.shape
# (3, 3, 1000)
% python3 script.py
(3, 3, 1000)
[[1. 2. 3.]
 [4. 5. 6.]
 [7. 8. 9.]]
[[1000. 2000. 3000.]
 [4000. 5000. 6000.]
 [7000. 8000. 9000.]]

你需要了解这个问题。底线是:

两个阵列需要具有相同数量的轴和轴 每个轴上的尺寸必须相同或其中一个必须为1。 您只能将形状为3,3的对象与形状为3,3,3,1或1,3的对象相乘并排列。还有其他广播规则。读它们

您的形状是3、3和1000,。正如你所说,你需要最终的形状是三维的。3需要匹配长度为1的轴。和1000一样。因此,您可以向每个轴添加轴,以形状3、3、1和1、1、1000结束:

c = a[:, :, np.newaxis]* b[np.newaxis,np.newaxis]

你需要了解这个问题。底线是:

两个阵列需要具有相同数量的轴和轴 每个轴上的尺寸必须相同或其中一个必须为1。 您只能将形状为3,3的对象与形状为3,3,3,1或1,3的对象相乘并排列。还有其他广播规则。读它们

您的形状是3、3和1000,。正如你所说,你需要最终的形状是三维的。3需要匹配长度为1的轴。和1000一样。因此,您可以向每个轴添加轴,以形状3、3、1和1、1、1000结束:

c = a[:, :, np.newaxis]* b[np.newaxis,np.newaxis]

+我接受这个答案,因为它是我申请的最佳答案。在阅读了关于einsum的内容后,我认为这实际上可以同时做更多我需要的事情,而且效率更高。。谢谢!。bousof的答案也不错,我只是更喜欢这个…einsum是一个漂亮的函数,我同意。+1我接受这个答案,因为它是我应用程序的最佳答案。在阅读了关于einsum的内容后,我认为这实际上可以同时做更多我需要的事情,而且效率更高。。谢谢!。bousof的答案也不错,我只是更喜欢这个…einsum是一个美丽的函数,我同意。这并不是给出一个维数为3,31000的数组,而是一个维数为1000,3,3的数组。如果你这样做的话,你还需要将结果转换成3,31000的形状。我必须承认,与Chris和bousof的前两个解决方案相比,我更喜欢这个解决方案。在答案中修复了它。这不会给出一个维数为3,31000的数组,而是一个维数为1000,3,3的数组。如果你这样做的话,你还需要将结果转换成3,31000的形状。我必须承认,与Chris和bousof的前两个解决方案相比,我更喜欢这个解决方案。在答案中修复了它。np。外部文档应该清楚,它是用于1d输入的。然而,np.outera,b.Reformate3,31000可能正好做到了这一点。这扭转了外层空间的扁平化。有趣。虽然我不明白如何重塑。。会改变一切。np.外部。。引发了一个异常,访问返回值的成员方法如何改变这个事实?np.outer文档应该清楚它是用于1d输入的。然而,np.outera,b.Reformate3,31000可能正好做到了这一点。这扭转了外层空间的扁平化。有趣。虽然我不明白如何重塑。。会改变一切。np.外部。。引发一个异常,访问返回值的成员方法将如何更改该事实?不需要b整形;广播负责自动引导维度。但明确增加这些维度并没有坏处;广播负责自动引导维度。但明确添加这些维度并没有什么坏处。