Шаг 45.
Однострочники Python. Наука о данных. Когда использовать в NumPy функцию sort(), а когда - argsort(). Код и принцип работы

    На этом шаге мы рассмотрим пример задачи, решение которой использует эти функции.

Код

    Следующий однострочник выясняет имена трех абитуриентов с самыми высокими оценками SAT. Обратите внимание, что нам нужны имена абитуриентов, а не отсортированные оценки SAT. Взгляните на данные и попытайтесь сами найти однострочное решение. И лишь затем разберите пример 3.23.


Пример 3.23. Однострочное решение, включающее функцию argsort() и срез с отрицательным значением шага
## Зависимости
import numpy as np

## Данные: оценки за экзамен SAT для различных абитуриентов
sat_scores = np.array([1100, 1256, 1543, 1043, 989, 1412, 1343])
students = np.array(["John", "Bob", "Alice", "Joe", "Jane", "Frank", "Carl"])

## Однострочник
top_3 = students[np.argsort(sat_scores)][:-4:-1]

## Результат
print(top_3)
Архив с файлом можно взять здесь.

    Как обычно, попробуйте догадаться, какими будут результаты.

Принцип работы

    Наши исходные данные состоят из оценок SAT абитуриентов в виде одномерного массива данных и еще одного массива с соответствующими именами абитуриентов. Например, Джон набрал на этом экзамене вполне приличную оценку в 1100, а Фрэнк показал великолепный результат - 1412.

    Наша задача - выяснить имена трех лучших абитуриентов. Для этого мы не просто отсортировали оценки SAT, а воспользовались функцией argsort(), чтобы получить массив с исходными индексами в новых, отсортированных позициях.

    Вот результаты работы функции argsort() для оценок SAT:

print(np.argsort(sat_scores))
# [4 3 0 1 6 5 2]

    Индексы необходимо сохранить, чтобы узнать имена абитуриентов из массива students, соответствующие исходным позициям в массиве. На первой позиции результата находится индекс 4, поскольку у Джейн самая низкая оценка SAT, равная 989 баллам. Обратите внимание, что и sort(), и argsort() сортируют в порядке возрастания, от самых низких значений к самым высоким.

    Получив отсортированные индексы, можно узнать имена соответствующих абитуриентов с помощью доступа по индексу к массиву students:

print(students[np.argsort(sat_scores)])
# ['Jane' 'Joe' 'John' 'Bob' 'Carl' 'Frank' 'Alice']

    Возможность библиотеки NumPy переупорядочивать последовательность с помощью расширенного доступа по индексу очень удобна. Если указать последовательность индексов, то NumPy запускает расширенный доступ по индексу и возвращает новый массив NumPy с элементами, переупорядоченными так, как указано в этой последовательности. Например, результат вычисления команды students[np.argsort(sat_scores)] равен students[[4 3 0 1 6 5 2]], вследствие чего NumPy создает следующий новый массив:

[students[4] students[3] students[0] students[1] students[6] students[5] students[2]]

    Из этого ясно, что у Джейн самые низкие оценки SAT, а у Алисы - самые высокие. Осталось только инвертировать список и извлечь из него трех лучших абитуриентов с помощью простого среза:

## Однострочник
top_3 = students[np.argsort(sat_scores)][:-4:-1]

## Результат 
print(top_3)
# ['Alice' 'Frank' 'Carl']

    У Алисы, Фрэнка и Карла самые высокие оценки SAT: 1543, 1412 и 1343 соответственно.

    Итак, вы изучили приложение двух важных функций NumPy: sort() и argsort(). Далее вам предстоит еще больше улучшить свое знание доступа по индексу и срезов в NumPy, воспользовавшись булевым доступом по индексу и лямбда-функциями в практическом примере исследования данных.

    На следующем шаге мы рассмотрим фильтрацию массивов с помощью лямбда-функций и булев доступ по индексу.




Предыдущий шаг Содержание