2016-08-02 105 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