Сортировка и вычисляемые столбцы
Отобранные данные обычно нужно упорядочить («топ-10 товаров») и дополнить вычисленными значениями («цена со скидкой», «место в рейтинге»). В этой теме — инструменты для этого.
Сортировка
import pandas as pd
df = pd.DataFrame({
"имя": ["Вика", "Аня", "Боря", "Гоша"],
"баллы": [85, 92, 85, 70],
"время": [30, 45, 25, 30],
})
print(df.sort_values("баллы")) # по возрастанию
print(df.sort_values("баллы", ascending=False)) # по убыванию
По нескольким столбцам
Список столбцов задаёт порядок сравнения: сначала по первому, при равенстве — по второму и так далее. Для каждого столбца можно указать своё направление:
df.sort_values(["баллы", "время"], ascending=[False, True])
Здесь выше тот, у кого больше баллов, а при равных баллах — у кого меньше время.
Сортировка возвращает новую таблицу и не меняет исходную. Индекс строк переезжает вместе со строками; чтобы пронумеровать заново, используют reset_index(drop=True).
head(k) после сортировки — классический способ взять «топ-k». Есть и короче: df.nlargest(3, "баллы"), df.nsmallest(3, "время").
map — замена по словарю
map заменяет каждое значение столбца по словарю (или функции):
sizes = pd.Series(["S", "L", "M"])
print(sizes.map({"S": 1, "M": 2, "L": 3})) # 1, 3, 2
Значения, которых нет в словаре, превращаются в NaN — их можно заменить: .fillna(0).
apply — своя функция
apply вызывает функцию для каждого значения Series:
def grade(score):
if score >= 90:
return "отлично"
if score >= 75:
return "хорошо"
return "надо подтянуть"
df["оценка"] = df["баллы"].apply(grade)
У таблицы apply(функция, axis=1) вызывает функцию для каждой строки — внутри доступны все столбцы строки:
df["темп"] = df.apply(lambda row: row["баллы"] / row["время"], axis=1)
Но построчный apply медленный: если выражение можно записать операциями над столбцами (df["баллы"] / df["время"]), так и делай — это в десятки раз быстрее.
Округление
df["темп"] = (df["баллы"] / df["время"]).round(2)
Для вывода с ровно двумя знаками используй форматирование: f"{x:.2f}".
rank — места
rank вычисляет место каждого значения. Параметр method задаёт, что делать с одинаковыми значениями:
scores = pd.Series([92, 85, 85, 70])
print(scores.rank(ascending=False, method="min")) # 1, 2, 2, 4
print(scores.rank(ascending=False, method="dense")) # 1, 2, 2, 3
print(scores.rank(ascending=False, method="first")) # 1, 2, 3, 4
min— одинаковым значениям наименьшее общее место, следующее место пропускается (как в спорте);dense— без пропусков;first— по порядку появления.
rank возвращает дробные числа (1.0), для вывода превращай в целые: .astype(int).
Итог
sort_values(столбцы, ascending=[...])— сортировка по нескольким признакам с разными направлениями;head(k),nlargest,nsmallest— первые k;map(словарь)— замена значений, отсутствующие становятсяNaN;apply(функция)— своя функция для значений;axis=1— для строк, но это медленно;rank(method="min"/"dense"/"first")— места.