我有两个Numpy数组x,形状(m,i)和y形状(m,j)(因此行数相同).我想将x的每一列与y元素的每一列相乘,以便结果具有形状(m,i * j).
例:
import numpy as np
np.random.seed(1)
x = np.random.randint(0, 2, (10, 3))
y = np.random.randint(0, 2, (10, 2))
这将创建以下两个数组x:
array([[1, 1, 0],
[0, 1, 1],
[1, 1, 1],
[0, 0, 1],
[0, 1, 1],
[0, 0, 1],
[0, 0, 0],
[1, 0, 0],
[1, 0, 0],
[0, 1, 0]])
和y:
array([[0, 0],
[1, 1],
[1, 1],
[1, 0],
[0, 0],
[1, 1],
[1, 1],
[1, 1],
[0, 1],
[1, 0]])
现在的结果应该是:
array([[0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0]])
目前,我已经在x和y的列上使用两个嵌套循环实现了此操作:
def _mult(x, y):
r = []
for xc in x.T:
for yc in y.T:
r.append(xc * yc)
return np.array(r).T
但是,我很确定必须有一个更优雅的解决方案,我似乎无法想出.
解决方法:
(y[:,None]*x[...,None]).reshape(x.shape[0],-1)
说明
作为投入,我们有 –
y : 10 x 2
x : 10 x 3
使用y [:,None],我们在现有的两个dims之间引入了一个新轴,从而创建了它的3D数组版本.这使第一个轴保持为3D版本中的第一个轴,并将第二个轴作为第三个轴推出.
使用x […,None],我们引入一个新轴作为最后一个轴,通过将两个现有的dims作为前两个dims推高以产生3D阵列版本.
总而言之,随着新轴的引入,我们有 –
y : 10 x 1 x 2
x : 10 x 3 x 1
使用y [:,None] * x […,None],y和x都会有广播,从而产生一个形状为(10,3,2)的输出数组.要获得形状(10,6)的最终输出数组,我们只需要将最后两个轴与该重塑合并.
标签:python,vectorization,numpy
来源: https://codeday.me/bug/20190527/1166128.html