У меня есть такой фрейм данных Polars:
Я пытаюсь присвоить номер каждой группе (c2, c3) внутри c1, чтобы это выглядело так:
Как мне это сделать?
Я вижу, как сделать глобальный рейтинг:
df.join(
df.select(["c1", "c2", "c3"])
.unique()
.with_columns(rank=pl.int_range(1, pl.len() + 1),
on=["c1", "c2", "c3"]
)
но это глобальный рейтинг, а не рейтинг внутри группы c1. Мне также интересно, можно ли сделать это с помощью over() вместо шаблона groupby/join.
да, спасибо за исправление!
Создайте структуру столбцов c2
, c3
, используя pl.struct("c2", "c3")
, вычислите плотный ранг по c1
, а затем вычтите 1, поскольку по умолчанию ранги начинаются с 1:
pl.struct("c2", "c3").rank("dense").over("c1") - 1
Полный код:
import polars as pl
df = pl.DataFrame(
{
"c1": ["a", "a", "a", "a", "d", "d"],
"c2": ["a", "a", "b", "c", "a", "b"],
"c3": [1, 1, 1, 1, 1, 1],
}
)
df2 = df.with_columns(rank=pl.struct("c2", "c3").rank("dense").over("c1") - 1)
print(df2)
Выход:
┌─────┬─────┬─────┬──────┐
│ c1 ┆ c2 ┆ c3 ┆ rank │
│ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ str ┆ i64 ┆ u32 │
╞═════╪═════╪═════╪══════╡
│ a ┆ a ┆ 1 ┆ 0 │
│ a ┆ a ┆ 1 ┆ 0 │
│ a ┆ b ┆ 1 ┆ 1 │
│ a ┆ c ┆ 1 ┆ 2 │
│ d ┆ a ┆ 1 ┆ 0 │
│ d ┆ b ┆ 1 ┆ 1 │
└─────┴─────┴─────┴──────┘
Разве ранг последней строки не должен быть равен 1?