如何将一个numpy数组中的行与另一个数组中的多列相乘?
我有一个棘手的问题 我有一个2D值数组如何将一个numpy数组中的行与另一个数组中的多列相乘?,numpy,Numpy,我有一个棘手的问题 我有一个2D值数组 vals=np.array([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]], np.float32) 和二维比例因子数组 factors=np.array([[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]]) 我想将VAL中的每一行与因子中的每一行相乘,得到一个“scaled_vals”数组,如下所示 注意:此输出已从我的原始帖子中更正-我对这一错误表示歉意 [[ 1. 2.
vals=np.array([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]], np.float32)
和二维比例因子数组
factors=np.array([[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]])
我想将VAL中的每一行与因子中的每一行相乘,得到一个“scaled_vals”数组,如下所示
注意:此输出已从我的原始帖子中更正-我对这一错误表示歉意
[[ 1. 2. 3.]
[ 8. 10. 12.]
[21. 24. 27.]]
[[ 4. 8. 12.]
[20. 25. 30.]
[42. 48. 54.]]
我只是用两列数据显示因子,但实际上它是“n”
任何帮助都将受到感激
道格
===
从评论中复制:
for step in range(2):
scaled_vals = np.multiply(vals, factors[0:,step:step+1])
我唯一能理解输入和输出的方法是,将每行VAL与所有因子的相应索引相乘,但需要匹配因子和VAL的维度
import numpy as np
vals=np.array([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]], np.float32) # shape = mxn
print(vals.shape)
factors=np.array([[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]]) # shape = nxk increasing dim to match with vals.shape
m = vals.shape[0]
n = vals.shape[1]
k = factors.shape[1]
print(factors.shape)
result = np.array([np.array([vals[j]*np.repeat(factors[:,i], n).reshape(n,n) for i in range(k)]) for j in range(m)])
print(result[0])
播放
广播
:
vals[:, None, None, :] * factors.T[None, :, :, None]
输出:
array([[[[ 1., 2., 3.],
[ 2., 4., 6.],
[ 3., 6., 9.]],
[[ 4., 8., 12.],
[ 5., 10., 15.],
[ 6., 12., 18.]]],
[[[ 4., 5., 6.],
[ 8., 10., 12.],
[12., 15., 18.]],
[[16., 20., 24.],
[20., 25., 30.],
[24., 30., 36.]]],
[[[ 7., 8., 9.],
[14., 16., 18.],
[21., 24., 27.]],
[[28., 32., 36.],
[35., 40., 45.],
[42., 48., 54.]]]])
您显示的(2,3,3)块可以通过以下方式生成:
In [267]: vals[0,:]*factors.T[:,:,None]
Out[267]:
array([[[ 1., 2., 3.],
[ 2., 4., 6.],
[ 3., 6., 9.]],
[[ 4., 8., 12.],
[ 5., 10., 15.],
[ 6., 12., 18.]]])
但评论循环是
In [268]: for step in range(2):
...: print(np.multiply(vals, factors[0:,step:step+1]))
...:
[[ 1. 2. 3.]
[ 8. 10. 12.]
[21. 24. 27.]]
[[ 4. 8. 12.]
[20. 25. 30.]
[42. 48. 54.]]
In [269]: vals*factors.T[:,:,None]
Out[269]:
array([[[ 1., 2., 3.],
[ 8., 10., 12.],
[21., 24., 27.]],
[[ 4., 8., 12.],
[20., 25., 30.],
[42., 48., 54.]]])
您可以使用
einsum
一条直线(不带循环)将索引乘以所需的任何形状:
output = np.einsum('ij,kl->ilkj',vals,factors)
这将[i,j]
从VAL
乘以[k,l]
从因子
并将其置于输出中的[i,l,k,j]
。注@Quan Hoang的答案(向上投票)同样没有循环。然而,我认为这更具可读性,您可以将其扩展到您想要的任何其他组合
输出:
[[[[ 1. 2. 3.]
[ 2. 4. 6.]
[ 3. 6. 9.]]
[[ 4. 8. 12.]
[ 5. 10. 15.]
[ 6. 12. 18.]]]
[[[ 4. 5. 6.]
[ 8. 10. 12.]
[12. 15. 18.]]
[[16. 20. 24.]
[20. 25. 30.]
[24. 30. 36.]]]
[[[ 7. 8. 9.]
[14. 16. 18.]
[21. 24. 27.]]
[[28. 32. 36.]
[35. 40. 45.]
[42. 48. 54.]]]]
[[[ 1. 2. 3.]
[ 8. 10. 12.]
[21. 24. 27.]]
[[ 4. 8. 12.]
[20. 25. 30.]
[42. 48. 54.]]]
更新:根据评论中提到的新乘法,解决方案为:
output = np.einsum('ij,ik->kij',vals,factors)
这将VAL中的[i,j]
乘以因子中的[i,k]
,并将其置于输出中的[k,i,j]
输出:
[[[[ 1. 2. 3.]
[ 2. 4. 6.]
[ 3. 6. 9.]]
[[ 4. 8. 12.]
[ 5. 10. 15.]
[ 6. 12. 18.]]]
[[[ 4. 5. 6.]
[ 8. 10. 12.]
[12. 15. 18.]]
[[16. 20. 24.]
[20. 25. 30.]
[24. 30. 36.]]]
[[[ 7. 8. 9.]
[14. 16. 18.]
[21. 24. 27.]]
[[28. 32. 36.]
[35. 40. 45.]
[42. 48. 54.]]]]
[[[ 1. 2. 3.]
[ 8. 10. 12.]
[21. 24. 27.]]
[[ 4. 8. 12.]
[20. 25. 30.]
[42. 48. 54.]]]
你能解释一下你是如何得到输出的吗?我无法理解乘法的任何组合。这只是输出的第一个元素吗?使用循环为范围(2)中的步长生成输出:scaled_vals=np.multiply(vals,factors[0:,step:step+1])现在我明白了。谢谢你的澄清。我有一个简单的一行解决方案,我张贴和索引,使它非常可读。所有-我完全搞砸了我的问题-我为浪费大家的时间道歉。我实际上试图实现的输出是,[[1.2.3.][8.10.12.][21.24.27.][[4.8.12.][20.25.30.][42.48.54.]]这就是循环实际产生的结果,正如HPaulj所指出的,您可以轻松地将我的帖子修改到您的设置中。我将在以后编辑此评论要求。我想应该是“ij,ik->kij'Ehsan”-谢谢你。我以前从未使用过einsum-非常有用!!!!我不确定是将这个答案标记为最佳解决方案还是来自Quang的解决方案,因为两者都给出了我需要的结果,并且几乎同时运行。我之所以选择这一款,是因为它的速度快了一点,并向我介绍了一种新的功能……我很高兴它对我有所帮助。einsum的强大功能超越了这个例子。知道它的力量,你会喜欢使用它。