我想对整个矩阵进行排序,并得到一个索引向量。在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中找到一个类似的简单命令。或者是否有一些同样方便的方法将矩阵也作为矢量处理。
答案 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.argwhere
对np.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]]
请注意,索引对列表的类型不能用于索引a
。 Out[369]
是在二维数组中索引项目的正确形式。我不熟悉R
,但看起来它的索引样式可能更像MATLAB。