获取有序矩阵索引的简单方法

时间:2017-12-02 16:03:04

标签: python sorting numpy matrix

我想对整个矩阵进行排序,并得到一个索引向量。在R中,这可以通过命令

简单地实现
order("matrix")

在Python中,类似的命令是:

np.argsort("matrix", axis=None)

问题在于,虽然R也识别矩阵的向量索引(即matrix[1]给出一个数字而不是一行),但在Python中我们似乎总是需要两个indeces。

所以我必须按照this问题中的步骤操作。但我需要更改代码,因为zip()似乎只能与Python 3+中的list()一起正常工作(或者我错了?)。新代码将是

import numpy as np    
a = np.array([[1,4,3],[2,8,0]])
n = a.shape[1]
d = list(zip( np.argsort(a, axis=None).__divmod__(n)))
d = list(zip(d[0][0], d[1][0]))

但R代码很简单!因此我想知道是否不可能在Python中找到一个类似的简单命令。或者是否有一些同样方便的方法将矩阵也作为矢量处理。

2 个答案:

答案 0 :(得分:2)

  在Python中,我们似乎总是需要两个indeces

事实并非如此。您可以使用平坦索引访问2D数组(或N-D数组)的元素,如argsort返回的索引5,0,3,2,1,4。这可以通过使用ravel来完成,它会在您的n维数组中创建一维视图。

a = np.array([[1, 4, 3], [2, 8, 0]])
ix = np.argsort(a, axis=None)
print(a.ravel()[ix])

打印[0,1,2,3,4,8],根据argsort生成的索引返回数组元素。

这也可以用于写入数组:例如,

a.ravel()[ix[0]] = 42

用42替换数组的最小元素。

请注意,传递axis=None会使argsort在排序前隐式展平数组,相当于ravel方法。

答案 1 :(得分:2)

您的d

In [362]: d
Out[362]: [(1, 2), (0, 0), (1, 0), (0, 2), (0, 1), (1, 1)]
带有argsort

None生成数组展平版本的排序索引:

In [366]: np.argsort(a, axis=None)
Out[366]: array([5, 0, 3, 2, 1, 4], dtype=int32)
In [368]: a.flat[_]           # apply this index to flattened a
Out[368]: array([0, 1, 2, 3, 4, 8])

np.argsort(a.flat)做同样的事情。 (或者如果对你更有意义,请使用a.ravel()。)

我们可以unravel 1d指数:

In [369]: np.unravel_index(Out[366], a.shape)
Out[369]: 
(array([1, 0, 1, 0, 0, 1], dtype=int32),
 array([2, 0, 0, 2, 1, 1], dtype=int32))

这使用与您相同的divmod计算。它可以直接用于索引a

In [370]: a[_]
Out[370]: array([0, 1, 2, 3, 4, 8])

transpose可以将数组的数组转换为类似于d的二维数组:

In [371]: np.transpose(__)
Out[371]: 
array([[1, 2],
       [0, 0],
       [1, 0],
       [0, 2],
       [0, 1],
       [1, 1]], dtype=int32)

np.argwherenp.where的结果做同样的事情。)

或在一行

In [375]: np.transpose(np.unravel_index(np.argsort(a, axis=None), a.shape)).tolist()
Out[375]: [[1, 2], [0, 0], [1, 0], [0, 2], [0, 1], [1, 1]]

请注意,索引对列表的类型不能用于索引aOut[369]是在二维数组中索引项目的正确形式。我不熟悉R,但看起来它的索引样式可能更像MATLAB。