2016-08-02 103 views
4

我有两个Numpy阵列x形状(m, i)y与形状(m, j)(所以行数是相同的)。我想将每列x与每列y逐元素相乘,以便结果形状为(m, i*j)从2D阵列乘以每列与另一个2D阵列的每列

实施例:

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]]) 

目前,我过的xy列执行此操作有两个嵌套的循环:

def _mult(x, y): 
    r = [] 
    for xc in x.T: 
     for yc in y.T: 
      r.append(xc * yc) 
    return np.array(r).T 

不过,我敢肯定,必须有一个更好的解决方案,我可以似乎没有想到。

回答

6

使用NumPy broadcasting -

(y[:,None]*x[...,None]).reshape(x.shape[0],-1) 

说明

作为输入,我们有 -

y : 10 x 2 
x : 10 x 3 

随着y[:,None],我们引入现有的两个DIMS之间的新的轴,从而创建一个3D阵列版本。这将第一个轴保持为3D版本中的第一个轴,并将第二个轴作为第三个轴。

随着x[...,None],我们推出了一个新的轴作为最后一个推动两个现有的暗淡作为前两个暗淡导致3D阵列版本。

总之,与引进的新的轴,我们有 -

y : 10 x 1 x 2 
x : 10 x 3 x 1 

随着y[:,None]*x[...,None],就不会有broadcasting两个yx,导致与的(10,3,2)的形状的输出阵列。为了得到形状为(10,6)的最终输出数组,我们只需要将最后两个轴与该整形合并即可。

+0

“复杂”的黑客,但非常简洁! +1 –

+0

你可以在这里添加一些解释吗?它简洁但不能说明问题。 – kmario23

+0

@ kmario23添加了一些解释,看看吧! – Divakar