Min/max 个广播数组

Min/max of broadcasted arrays

有没有一种方法可以有效地比较同时广播的多个数组?例如:

a = np.arange( 0,  9).reshape(3,3)
b = np.arange( 9, 18).reshape(3,3)
c = np.arange(18, 27).reshape(3,3)

如果我将这些广播如下:

abc = a[:,:,None,None,None,None] + b[None,None,:,:,None,None] + c[None,None,None,None,:,:]

然后 abc 的每个元素等于 a_ij + b_kl + c_mn 其中 ijklmn 索引各自的数组。相反,我想要的是 min(a_ij, b_kl, c_mn),或者理想情况下 max(a_ij, b_kl, c_mn) - min(a_ij, b_kl, c_mn)。有没有一种有效的方法可以做到这一点?

当然,我可以将临时数组广播为:

Abc =     a[:,:,None,None,None,None] + 0 * b[None,None,:,:,None,None] + 0 * c[None,None,None,None,:,:]
aBc = 0 * a[:,:,None,None,None,None] +     b[None,None,:,:,None,None] + 0 * c[None,None,None,None,:,:]
abC = 0 * a[:,:,None,None,None,None] + 0 * b[None,None,:,:,None,None] +     c[None,None,None,None,:,:]

然后从这些数组中找到 min/max,但是,这些数组可能会变得非常大。如果有办法一步到位就更好了

另外请注意,这些数组保证可广播,但不一定具有相同的形状(例如,(1, 3)(3, 3))。

您可以通过对 ab:

进行操作来存储中间数组(无论如何都小于最终结果)
temp = np.minimum.outer(a.ravel(), b.ravel())
res = np.minimum.outer(temp.ravel(), c.ravel())

然后用 c 重复相同的操作。 minimum 计算 2 个数组的逐元素最小值。由于它是 ufunc,您可以使用 outer 将该操作应用于这 2 个数组的所有值对。

您可以根据需要重塑 res

编辑#1

感谢 P.Panzer 的评论,您不需要将一维数组与 ufunc.outer 一起使用,这样代码就更简单了:

temp = np.minimum.outer(a, b)
res = np.minimum.outer(temp, c)