Решение:
>>> a[np.arange(np.shape(a)[0])[:,np.newaxis], np.argsort(a)]
array([[1, 2, 3],
[2, 8, 9]])
Вы получили это право, хотя я бы не назвал это как обман индексации.
Может быть, это поможет сделать его более ясным:
In [544]: i=np.argsort(a,axis=1)
In [545]: i
Out[545]:
array([[1, 2, 0],
[2, 0, 1]])
i
является порядок, что мы хотим, для каждой строки. То есть:
In [546]: a[0, i[0,:]]
Out[546]: array([1, 2, 3])
In [547]: a[1, i[1,:]]
Out[547]: array([2, 8, 9])
Чтобы сделать оба шага индексации сразу, мы должны использовать индекс «столбца» для 1-го измерения.
In [548]: a[[[0],[1]],i]
Out[548]:
array([[1, 2, 3],
[2, 8, 9]])
Другой массив, который может работать в паре с i
является:
In [560]: j=np.array([[0,0,0],[1,1,1]])
In [561]: j
Out[561]:
array([[0, 0, 0],
[1, 1, 1]])
In [562]: a[j,i]
Out[562]:
array([[1, 2, 3],
[2, 8, 9]])
Если i
идентифицирует столбец для каждого элемента, то j
указывает строку для каждого элемента. Графический массив [[0],[1]]
работает так же хорошо, потому что он может транслироваться с i
.
Я думаю
np.array([[0],
[1]])
как 'короткой руки' для j
. Вместе они определяют исходную строку и столбец каждого элемента нового массива. Они работают вместе, а не последовательно.
Полное отображение a
в новом массиве:
[a[0,1] a[0,2] a[0,0]
a[1,2] a[1,0] a[1,1]]
def foo(a):
i = np.argsort(a, axis=1)
return (np.arange(a.shape[0])[:,None], i)
In [61]: foo(a)
Out[61]:
(array([[0],
[1]]), array([[1, 2, 0],
[2, 0, 1]], dtype=int32))
In [62]: a[foo(a)]
Out[62]:
array([[1, 2, 3],
[2, 8, 9]])
Спасибо @hpaulj, действительно полезные объяснения! Если у вас есть секунда, можете ли вы объяснить «индекс столбца [ing] для первого измерения»? Это просто преобразование массива в (2,1,3) вправо ... почему это облегчает обработку 'i'? – DilithiumMatrix
Я расширил свое объяснение. – hpaulj
есть ли более простой способ сделать это? Я думал, что argsort должен был подумать, для чего он будет использоваться после сортировки массивов? ..... – Martian2049