将2D数组中的每列与另一个2D数组中的每列相乘

cbr*_*rnr 4 python numpy vectorization

我有两个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))
Run Code Online (Sandbox Code Playgroud)

这将创建以下两个数组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]])
Run Code Online (Sandbox Code Playgroud)

并且y:

array([[0, 0],
       [1, 1],
       [1, 1],
       [1, 0],
       [0, 0],
       [1, 1],
       [1, 1],
       [1, 1],
       [0, 1],
       [1, 0]])
Run Code Online (Sandbox Code Playgroud)

现在的结果应该是:

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]])
Run Code Online (Sandbox Code Playgroud)

目前,我过的列执行此操作有两个嵌套循环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
Run Code Online (Sandbox Code Playgroud)

但是,我很确定必须有一个更优雅的解决方案,我似乎无法想出.

Div*_*kar 6

使用NumPy broadcasting-

(y[:,None]*x[...,None]).reshape(x.shape[0],-1)
Run Code Online (Sandbox Code Playgroud)

说明

作为投入,我们有 -

y : 10 x 2
x : 10 x 3
Run Code Online (Sandbox Code Playgroud)

有了y[:,None],我们在现有的两个dims之间引入了一个新轴,从而创建了3D它的数组版本.这使第一个轴保持为3D版本中的第一个轴,并将第二个轴作为第三个轴推出.

有了x[...,None],我们引入了一个新的轴作为最后一个轴,通过推动两个现有的dims作为前两个dims导致3D数组版本.

总而言之,随着新轴的引入,我们有 -

y : 10 x 1 x 2
x : 10 x 3 x 1
Run Code Online (Sandbox Code Playgroud)

使用时y[:,None]*x[...,None],会有broadcasting两个yx,导致输出数组的形状为(10,3,2).要获得最终的输出形状数组(10,6),我们只需要将最后两个轴与该重塑形状合并.