Python NumPy是否提供分层广播?

Python NumPy是否提供分层广播?,python,arrays,numpy,array-broadcasting,Python,Arrays,Numpy,Array Broadcasting,我想知道是否有一个内置操作可以将我的代码从Python循环中解放出来 问题是:我有两个矩阵A和BA有N行和B有N列。我想将A中的每一行I与B中相应的I列相乘(使用NumPy广播)。结果矩阵将在输出中形成i层。所以我的结果是三维数组 这样的操作在NumPy中可用吗?是的,在最简单的形式中,您只需添加“零”维度,这样NumPy就会沿着A的行和B的列进行广播: >>> import numpy as np >>> A = np.arange(12).reshape

我想知道是否有一个内置操作可以将我的代码从Python循环中解放出来

问题是:我有两个矩阵
A
B
<代码>A有
N
行和
B
N
列。我想将
A
中的每一行
I
B
中相应的
I
列相乘(使用NumPy广播)。结果矩阵将在输出中形成
i
层。所以我的结果是三维数组


这样的操作在NumPy中可用吗?

是的,在最简单的形式中,您只需添加“零”维度,这样NumPy就会沿着
A
的行和
B
的列进行广播:

>>> import numpy as np

>>> A = np.arange(12).reshape(3, 4) # 3 row, 4 colums
>>> B = np.arange(15).reshape(5, 3) # 5 rows, 3 columns
>>> res = A[None, ...] * B[..., None]
>>> res
array([[[  0,   0,   0,   0],
        [  4,   5,   6,   7],
        [ 16,  18,  20,  22]],

       [[  0,   3,   6,   9],
        [ 16,  20,  24,  28],
        [ 40,  45,  50,  55]],

       [[  0,   6,  12,  18],
        [ 28,  35,  42,  49],
        [ 64,  72,  80,  88]],

       [[  0,   9,  18,  27],
        [ 40,  50,  60,  70],
        [ 88,  99, 110, 121]],

       [[  0,  12,  24,  36],
        [ 52,  65,  78,  91],
        [112, 126, 140, 154]]])
结果的形状为
(5,3,4)
,如果需要不同的形状,可以轻松地移动轴。例如,使用:


形状为
(3,4,5)

直接表达需求的一种方法是使用:

这使用了

关于进一步的讨论,见T.W.Körner的第3章。在这封信中,作者引用了爱因斯坦给朋友的信中一段有趣的话:

“我在数学上有了一个伟大的发现;每次必须对一个出现两次的索引进行求和时,我都会抑制求和符号……”


我喜欢这个解释是因为它的图形-谢谢,我会尝试更多,因为第一个检查是结果数组的上下角,它应该是
36
(而不是:-D)。深度应该是3。@greenoldman然后是
np.moveaxis(res,(0,1,2)、(2,0,1))
。从这个问题上看,不太清楚你想要什么样的结果形状,所以我做了一个猜测(哪一个是错误的):)谢谢你,我当然比你投的票高,但是很难选择接受哪一个答案,两者都很好,希望你不介意我按时完成:-)。
>>> np.moveaxis(res, (0, 1, 2), (2, 0, 1))  # 0 -> 2 ; 1 -> 0, 2 -> 1
array([[[  0,   0,   0,   0,   0],
        [  0,   3,   6,   9,  12],
        [  0,   6,  12,  18,  24],
        [  0,   9,  18,  27,  36]],

       [[  4,  16,  28,  40,  52],
        [  5,  20,  35,  50,  65],
        [  6,  24,  42,  60,  78],
        [  7,  28,  49,  70,  91]],

       [[ 16,  40,  64,  88, 112],
        [ 18,  45,  72,  99, 126],
        [ 20,  50,  80, 110, 140],
        [ 22,  55,  88, 121, 154]]])
>>> A = np.arange(12).reshape(3, 4)
>>> B = np.arange(15).reshape(5, 3)
>>> np.einsum('...i,j...->...ij', A, B)
array([[[  0,   0,   0,   0,   0],
        [  0,   3,   6,   9,  12],
        [  0,   6,  12,  18,  24],
        [  0,   9,  18,  27,  36]],

       [[  4,  16,  28,  40,  52],
        [  5,  20,  35,  50,  65],
        [  6,  24,  42,  60,  78],
        [  7,  28,  49,  70,  91]],

       [[ 16,  40,  64,  88, 112],
        [ 18,  45,  72,  99, 126],
        [ 20,  50,  80, 110, 140],
        [ 22,  55,  88, 121, 154]]])