我有一个矩阵:
A = [ [1,2],
[3,4],
[5,6] ]
和值向量:
V = [4,6,2]
我想使用V中的值重新排序A到第2列。结果应该是 是:
A = [ [3,4],
[5,6],
[1,2] ] # 2nd columns' values have the same order as V
怎么做?
答案 0 :(得分:7)
首先,我们需要在A
的第二列中找到我们需要与V
的顺序匹配的值的指标。在这种情况下,那是[1,2,0]
。一旦我们有了这些,我们就可以使用numpy的“花式”索引来完成剩下的工作。
所以,你可能会这样做:
import numpy as np
A = np.arange(6).reshape((3,2)) + 1
V = [4,6,2]
column = A[:,1].tolist()
order = [column.index(item) for item in V]
print A[order,:]
如果你想完全避免python列表,那么你可以做类似下面的事情。它是hackish,并且可能有更好的方式,但是......
我们可以滥用numpy.unique
来执行此操作...我在这里做的是取决于特定的实现细节(unique
似乎从数组的末尾开始),这可能会在任何时候......这就是让它成为丑陋黑客的原因。
import numpy as np
A = np.arange(6).reshape((3,2)) + 1
V = np.array([4,6,2])
vals, order = np.unique(np.hstack((A[:,1],V)), return_inverse=True)
order = order[-V.size:]
print A[order,:]
答案 1 :(得分:6)
@JoeKington's numpy solution非常聪明,但它依赖于A[:,1]
按排序顺序排列。以下是对一般情况的修复:
import numpy as np
np.random.seed(1)
N=5
A = np.arange(2*N).reshape((-1,2))+100
np.random.shuffle(A)
print(A)
如果A
看起来像这样:
[[104 105]
[102 103]
[108 109]
[100 101]
[106 107]]
和V
V = A[:,1].copy()
np.random.shuffle(V)
print(V)
看起来像这样:
[105 109 107 101 103]
然后我们使用Joe的解决方案:
vals, order = np.unique(np.hstack((A[:,1],V)), return_inverse=True)
但保存A[:,1]
和V
的顺序:
a_order = order[:V.size]
v_order = order[-V.size:]
并在使用A
重新排序之前对A[np.argsort(a_order)]
进行排序(通过形成v_order
):
print A[np.argsort(a_order)][v_order]
[[104 105]
[108 109]
[106 107]
[100 101]
[102 103]]
(A[np.argsort(a_order)]
根据第二列排序A
。)
请注意,np.unique始终按排序顺序返回数组。 The documentation保证return_inverse=True
返回的索引是重构原始数组的唯一数组的索引。也就是说,如果你这样叫np.unique
:
uniq_arr, indices = np.unique(arr, return_inverse=True)
你可以保证
unique_arr[indices] = arr
因为你可以依赖这种关系,所以Joe的方法不依赖于纯粹的实现细节 - unique
将始终以这种方式运行。 (着名的最后一句话 - 考虑np.unique1d
返回的order of output arguments发生的事情......但不要介意:))