Python numpy从三个元素中获取not min或max元素

Python numpy从三个元素中获取not min或max元素,python,numpy,Python,Numpy,我有一个三维阵列: y = np.random.randint(1,5 ,(50,50,3)) 我想计算第三个轴(3个元素)上的最大值和最小值,然后除以剩余的数字/元素 比如说: x = (np.max(y, axis =2) - 2*np.min(y, axis =2))/the third number 我不知道怎么打第三个号码。 需要注意的是,第三个数字可能等于最小值或最大值: e、 g.(5,5,1)方法#1 找到第三个的诀窍是从3那些最大和最小索引中减去。临界情况是最大和最小索引

我有一个三维阵列:

 y = np.random.randint(1,5 ,(50,50,3))
我想计算第三个轴(3个元素)上的最大值和最小值,然后除以剩余的数字/元素

比如说:

x = (np.max(y, axis =2) - 2*np.min(y, axis =2))/the third number
我不知道怎么打第三个号码。 需要注意的是,第三个数字可能等于最小值或最大值:

e、 g.(5,5,1)

方法#1

找到第三个的诀窍是从
3
那些最大和最小索引中减去。临界情况是最大和最小索引相同,即沿最后一个轴的所有三个元素都相同,第三个元素索引也相同

因此,我们将有一个这样的解决方案-

max_idx = y.argmax(2)
min_idx = y.argmin(2)

rem_idx = np.where(max_idx == min_idx, max_idx, 3 - max_idx - min_idx)
out = (y[all_idx(max_idx, 2)] -2*y[all_idx(min_idx, 2)])/y[all_idx(rem_idx, 2)]
辅助函数,用于索引到具有索引的
y
-

# https://stackoverflow.com/a/46103129/ @Divakar
def all_idx(idx, axis):
    grid = np.ogrid[tuple(map(slice, idx.shape))]
    grid.insert(axis, idx)
    return tuple(grid)
方法#2

我们可以沿着轴求和,然后减去最小值和最大值,得到第三个元素,然后简单地将其插入公式中-

maxv = np.max(y, axis =2)
minv = np.min(y, axis =2)
x = (maxv - 2*minv)/(y.sum(2) - maxv - minv)

当你只需要一个最大值和最小值时,排序通常是多余的,在这种情况下,我认为它是最简单的。它直接把我们想要的数字放在容易获取的地方,不需要任何复杂的算术运算

y = np.random.randint(1, 5, (50, 50,3))
y2 = y.copy()
y2.sort(axis=2)
sout = (y2[...,2] - 2 * y2[...,0]) / y2[...,1]
这让我

In [68]: (sout == divakar_out).all()
Out[68]: True

这通常是个好兆头

另一种选择是使用
np.median

(y.max(2) - 2 * y.min(2)) / np.median(y, 2)

作为一个选择,还不错!同样的答案,只是重新排列了
min,med,max=np.sort(y,axis=2),transpose(2,0,1);(max_-2*min_)/med_
再短一点:x,y,z=np.sort(a).T;((z-2*x)/y)。T@piRSquared是的,你喜欢那些总结,显然是点;)这就是我的总结(-:@Divakar是的,方法二感觉更自然(也更聪明).好吧,我觉得很遗憾,我没有想到这一个,这是我最喜欢的解决方案。我想我对中位数有一种心理障碍,因为在这种情况下,它可以返回一个不在序列中的值,但这在这里不适用。我只是在尝试给中间排序层一个名称后才想到它。当我决定
med
然后它变得显而易见。然而,您的解决方案要快得多,因为它使用一个非常短的排序来解析所有三个组件。