numpy.ndarray 排序到 return 个索引

numpy.ndarray sorting to return indices

errors = [[ 0.,  9., 12.,  9., 14.,  5.,  4., 10.,  8.,  8.,  6.,  5.,  9.],
   [ 9.,  0., 22., 16., 11., 12.,  9., 21., 14., 11., 16., 15.,  9.],
   [12., 22.,  0., 18., 23., 16., 10., 22., 21., 13., 13., 13., 15.],
   [ 9., 16., 18.,  0., 11., 12.,  8., 19., 20., 11.,  7.,  9., 13.],
   [14., 11., 23., 11.,  0., 11.,  7., 18.,  9., 10.,  7.,  7., 14.],
   [ 5., 12., 16., 12., 11.,  0.,  7., 13., 15.,  5.,  8., 10.,  9.],
   [ 4.,  9., 10.,  8.,  7.,  7.,  0.,  8.,  8.,  3.,  4.,  7.,  4.],
   [10., 21., 22., 19., 18., 13.,  8.,  0., 18., 12., 14., 13., 11.],
   [ 8., 14., 21., 20.,  9., 15.,  8., 18.,  0.,  5., 11., 16., 10.],
   [ 8., 11., 13., 11., 10.,  5.,  3., 12.,  5.,  0.,  8.,  9.,  5.],
   [ 6., 16., 13.,  7.,  7.,  8.,  4., 14., 11.,  8.,  0., 11.,  7.],
   [ 5., 15., 13.,  9.,  7., 10.,  7., 13., 16.,  9., 11.,  0.,  4.],
   [ 9.,  9., 15., 13., 14.,  9.,  4., 11., 10.,  5.,  7.,  4.,  0.]])

以上是 numpy.ndarray 的形状 (13,13),在使用 13 个特征中的两个特征的某个分类任务中获得错误。

这里的任务是找到最小的可实现误差并且 达到这个最小误差的一对特征

由于数据少,肉眼可见的最小误差是3,这对特征不是(6,9)就是(9,6)。

(0值的对角线本身就是特征,所以不包括在内)。

我尝试用 argsort 来做,但它只对每一行进行单独排序,我没有得到答案。

请协助。

如果我正确理解你的任务:

  • 在您的 errors-array
  • 中找到最小值
  • 找到这个最小误差的索引

我使用 min()nonzero() 实现了这一点。这是我对你的问题的解决方案:

errors = np.array((
   [ 0.,  9., 12.,  9., 14.,  5.,  4., 10.,  8.,  8.,  6.,  5.,  9.],
   [ 9.,  0., 22., 16., 11., 12.,  9., 21., 14., 11., 16., 15.,  9.],
   [12., 22.,  0., 18., 23., 16., 10., 22., 21., 13., 13., 13., 15.],
   [ 9., 16., 18.,  0., 11., 12.,  8., 19., 20., 11.,  7.,  9., 13.],
   [14., 11., 23., 11.,  0., 11.,  7., 18.,  9., 10.,  7.,  7., 14.],
   [ 5., 12., 16., 12., 11.,  0.,  7., 13., 15.,  5.,  8., 10.,  9.],
   [ 4.,  9., 10.,  8.,  7.,  7.,  0.,  8.,  8.,  3.,  4.,  7.,  4.],
   [10., 21., 22., 19., 18., 13.,  8.,  0., 18., 12., 14., 13., 11.],
   [ 8., 14., 21., 20.,  9., 15.,  8., 18.,  0.,  5., 11., 16., 10.],
   [ 8., 11., 13., 11., 10.,  5.,  3., 12.,  5.,  0.,  8.,  9.,  5.],
   [ 6., 16., 13.,  7.,  7.,  8.,  4., 14., 11.,  8.,  0., 11.,  7.],
   [ 5., 15., 13.,  9.,  7., 10.,  7., 13., 16.,  9., 11.,  0.,  4.],
   [ 9.,  9., 15., 13., 14.,  9.,  4., 11., 10.,  5.,  7.,  4.,  0.]))

min_error = errors[errors!=0].min()
pairs = np.nonzero(errors == errors[errors!=0].min())

这给了我预期的输出 min_error = 3pairs = (array([6, 9]), array([9, 6]))

严格来说,您需要屏蔽掉的不是零值,而是对角线值。谁知道呢,也许有一对会完美匹配。所以我会这样做:

# This modifies errors filling the diagonal with inf-s. Make a copy if you need to keep the original result intact.
np.fill_diagonal(errors, np.inf)
np.nonzero(errors == errors.min())