2025, Sep 27 05:17
Сортировка максимумов столбцов в pandas: sort_values против sort_index
Показываем, как в pandas получить максимумы по столбцам и отсортировать их по убыванию через sort_values, избегая ошибок Series и путаницы с sort_index.
Сортировать кумулятивную статистику в pandas несложно, если различать сортировку по индексам и сортировку по значениям. Частая ловушка возникает, когда вы считаете поколоночные максимумы и пытаетесь их упорядочить, а затем выясняется, что вы сортируете Series, а не DataFrame, и вызов сортировки обращается к неверной оси. Ниже — короткое руководство на реальном примере с накопленными суммами осадков по годам.
Краткий обзор задачи
Имеется многоколоночный DataFrame в pandas: каждая колонка — это год, а внутри — накопленные значения осадков по последовательным дням. Последняя запись в каждой колонке — её максимум. Требуется извлечь максимум по каждому году и отсортировать эти значения по убыванию. В первой попытке использовали сортировку по индексу, которая не меняет порядок так, как нужно, а попытка отсортировать по axis=1 завершается ошибкой, потому что результат — это Series.
Пример кода, который воспроизводит проблему
import pandas as pd
import os
rain_df = pd.read_csv('myfile.txt', sep=' ', skipinitialspace=True)
col_max = rain_df.max()
print(col_max)
# Попытка, которая сортирует метки, а не числовые значения
sorted_by_labels = col_max.sort_index()
print(sorted_by_labels)
Этот код возвращает Series с максимумами по каждой колонке. Метод sort_index переставляет элементы по меткам — например, Avge, 1945, 1946 и т. д., — а не по числовым максимумам. Попытка сортировать по axis=1 вызывает ошибку «ValueError: No axis named 1 for object type Series», что означает: у одномерного Series просто нет второй оси.
Что на самом деле происходит
Вызов DataFrame.max() по столбцам возвращает объект pandas Series: каждая метка индекса — это имя столбца (например, год), а значение — максимум для этого столбца. Сортировка этого Series по индексу переставляет метки, а не сами числовые максимумы. Поскольку Series одномерен, у него только одна ось; axis=1 для такого объекта не существует — отсюда и ошибка.
Решение: сортируйте по значениям по убыванию
Чтобы упорядочить максимумы от большего к меньшему, сортируйте Series по значениям. Главное — вызвать sort_values с параметром ascending=False.
import pandas as pd
import os
rain_df = pd.read_csv('myfile.txt', sep=' ', skipinitialspace=True)
col_max = rain_df.max()
ranked_max = col_max.sort_values(ascending=False)
print(ranked_max)
Так сохраняется соответствие между метками годов и их максимальными накопленными осадками, а результаты упорядочиваются от наибольшего к наименьшему.
Почему это важно
При агрегации по столбцам именно тип результата определяет дальнейшие действия. Для Series методы sort_index и sort_values работают с разными аспектами одних и тех же данных: с метками и с числами. Неверный выбор приводит к неудобному порядку элементов или к ошибкам о несуществующих осях. Понимание этой разницы гарантирует корректное ранжирование метрик, выбор топовых значений и формирование таблиц лидеров.
Итоги
После агрегирования вроде max по столбцам DataFrame помните, что на руках у вас Series. Если нужно упорядочить по величине, используйте sort_values с ascending=False. Если же важен алфавитный или хронологический порядок меток, применяйте sort_index. Согласованность типа объекта и цели сортировки экономит время и избавляет от лишних ошибок.
Статья основана на вопросе на StackOverflow от Zilore Mumba и ответе от 0ro2.