@ numpy решение ДжоКингтона очень умно, но полагается на 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]
тогда мы используем решение Джо:
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 всегда возвращает массив в отсортированном порядке. Документация гарантирует с return_inverse=True
, что возвращаемые индексы являются индексами уникального массива, который восстанавливает исходный массив. То есть, если вы позвоните np.unique
так:
uniq_arr, indices = np.unique(arr, return_inverse=True)
вам гарантировано, что
unique_arr[indices] = arr
Поскольку вы можете положиться на эти отношения, метод Джо не зависит от простой детали реализации - unique
всегда будет вести себя таким образом. (Известные последние слова - учитывая то, что случилось с порядком выходных аргументов , возвращаемым np.unique1d
... но не берите в голову:))