我有一个矩阵
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)
或者,我们可以将argmax
与np.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
以便沿着的第一个轴(行(对它们进行比较