将行最大值设置为1,将其他值设置为0



我有一个矩阵

x = array([[ 1,  2,  4,  6],
[ 8, 29, 11, 35],
[18, 16, 28, 25],
[26, 28, 53, 52]])

我想得到行和列的最大值和最小值,使其为1,其余为0。我用以下方法来获得列中的最大值和最小值:

getMax = np.where(x == np.amax(x, axis=0), 1, 0)
getMin = np.where(x == np.amin(x, axis=0), 1, 0)

这样做,我得到:

array([[0, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 0],
[1, 0, 1, 1]]) for maximum

array([[1, 1, 1, 1],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]) for minimum

但是当我做以下操作来获得行的最小值和最大值时

getMax = np.where(x == np.amax(x, axis=1), 1, 0)
getMin = np.where(x == np.amin(x, axis=1), 1, 0)

我得到这个:

array([[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 0]]) for maximum

array([[1, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]) for minimum

行中最小值和最大值的代码有什么错误?

在第二种情况下,要比较的轴没有对齐,您需要确保两个数组的尺寸相同。因此,您有keepdims,它正是为了保留输入形状。此外,不需要np.where,您可以直接转换为int:

(x == np.max(x, axis=1, keepdims=True)).view('i1')
array([[0, 0, 0, 1],
[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 1, 0]], dtype=int8)

或者,我们可以将argmaxnp.put_along_axis一起用于更高性能的方法:

getMax = np.zeros_like(x)
np.put_along_axis(getMax,x.argmax(1)[:,None],1,axis=1)

时间安排:

a = np.concatenate([x]*10000, axis=0)
%timeit np.where(a == np.amax(a, axis=1, keepdims=True), 1, 0)
# 1.15 ms ± 6.64 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit (a == np.amax(a, axis=1, keepdims=True)).view('i1')
# 986 µs ± 13.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
getMax = np.zeros_like(a)
np.put_along_axis(getMax,a.argmax(1)[:,None],1,axis=1)
# 436 µs ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

注意,如果你不保留2D形状,你会得到:

np.amax(x, axis=1)
#array([ 6, 35, 28, 53])

这是一个1D阵列,将沿着x中的最后一个轴进行比较。当比较两个阵列的尺寸时,这一点变得很清楚:

x.shape (2d array):                      4 x 4
np.amax(x, axis=1).shape (1d array):         4

而你真正想要的是:

x.shape (2d array):                          4 x 4
np.amax(x, axis=1, keepdims=True).shape:     4 x 1

以便沿着的第一个轴(行(对它们进行比较

相关内容