Как может я “архивировать вид”, параллельны массивам numpy?

Если я имею два параллельных списка и хочу отсортировать их по приказу элементов в первом, это очень легко:

>>> a = [2, 3, 1]
>>> b = [4, 6, 7]
>>> a, b = zip(*sorted(zip(a,b)))
>>> print a
(1, 2, 3)
>>> print b
(7, 4, 6)

Как я могу сделать то же использование numpy массивы, не распаковывая их в стандартные списки Python?

47
задан YGA 4 April 2019 в 15:34
поделиться

3 ответа

b [a.argsort ()] должен помочь.

Вот как это работает. Сначала вам нужно найти перестановку, которая сортирует. argsort - это метод, который вычисляет это:

>>> a = numpy.array([2, 3, 1])
>>> p = a.argsort()
>>> p
[2, 0, 1]

Вы можете легко проверить, что это правильно:

>>> a[p]
array([1, 2, 3])

Теперь примените ту же перестановку к b.

>>> b = numpy.array([4, 6, 7])
>>> b[p]
array([7, 4, 6])
70
ответ дан 26 November 2019 в 19:34
поделиться

Here's an approach that creates no intermediate Python lists, though it does require a NumPy "record array" to use for the sorting. If your two input arrays are actually related (like columns in a spreadsheet) then this might open up an advantageous way of dealing with your data in general, rather than keeping two distinct arrays around all the time, in which case you'd already have a record array and your original problem would be answered merely by calling sort() on your array.

This does an in-place sort after packing both arrays into a record array:

>>> from numpy import array, rec
>>> a = array([2, 3, 1])
>>> b = array([4, 6, 7])
>>> c = rec.fromarrays([a, b])
>>> c.sort()
>>> c.f1   # fromarrays adds field names beginning with f0 automatically
array([7, 4, 6])

Edited to use rec.fromarrays() for simplicity, skip redundant dtype, use default sort key, use default field names instead of specifying (based on this example).

22
ответ дан 26 November 2019 в 19:34
поделиться

Это может быть самый простой и наиболее общий способ делать то, что вы хотите. (Я использовал здесь три массива, но это будет работать с массивами любой формы, будь то два столбца или двести).

import numpy as NP
fnx = lambda : NP.random.randint(0, 10, 6)
a, b, c = fnx(), fnx(), fnx()
abc = NP.column_stack((a, b, c))
keys = (abc[:,0], abc[:,1])          # sort on 2nd column, resolve ties using 1st col
indices = NP.lexsort(keys)        # create index array
ab_sorted = NP.take(abc, indices, axis=0)

Одна из особенностей lexsort заключается в том, что вам нужно указать ключи в обратном порядке, т.е. ключ второй и ваш вторичный ключ сначала. В моем примере я хочу выполнить сортировку, используя второй столбец в качестве первичного ключа, поэтому я указываю его вторым; 1-й столбец разрешает только ничьи, но он указан первым).

2
ответ дан 26 November 2019 в 19:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: