Я хочу закодировать двоичные события non-zero целыми числами. Ниже приведена демонстрационная таблица:
import polars as pl
df = pl.DataFrame(
{
"event": [0, 1, 1, 0],
"foo": [1, 2, 3, 4],
"boo": [2, 3, 4, 5],
}
)
Ожидаемый результат достигается за счет:
df = df.with_row_index()
events = df.select(pl.col(["index", "event"])).filter(pl.col("event") == 1).with_row_index("event_id").drop("event")
df = df.join(events, on = "index", how = "left")
out:
shape: (4, 5)
┌───────┬───────┬─────┬─────┬──────────┐
│ index ┆ event ┆ foo ┆ boo ┆ event_id │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ u32 ┆ i64 ┆ i64 ┆ i64 ┆ u32 │
╞═══════╪═══════╪═════╪═════╪══════════╡
│ 0 ┆ 0 ┆ 1 ┆ 2 ┆ null │
│ 1 ┆ 1 ┆ 2 ┆ 3 ┆ 0 │
│ 2 ┆ 1 ┆ 3 ┆ 4 ┆ 1 │
│ 3 ┆ 0 ┆ 4 ┆ 5 ┆ null │
└───────┴───────┴─────┴─────┴──────────┘
Я хочу получить ожидаемый результат, соединив выражения:
(
df
.with_row_index()
.join(
df
.select(pl.col(["index", "event"]))
.filter(pl.col("event") == 1)
.with_row_index("event_id")
.drop("event"),
on = "index",
how = "left",
)
)
Однако выражения в выражении .join(), похоже, не добавили столбец index из операции df.with_row_index():
ColumnNotFoundError: index
Error originated just after this operation:
DF ["event", "foo", "boo"]; PROJECT */3 COLUMNS; SELECTION: "None"






Одним из возможных решений является использование оператора :=:
df = (df := df.with_row_index()).join(
df.select(pl.col(["index", "event"]))
.filter(pl.col("event") == 1)
.with_row_index("event_id")
.drop("event"),
on = "index",
how = "left",
)
print(df)
Распечатки:
shape: (4, 5)
┌───────┬───────┬─────┬─────┬──────────┐
│ index ┆ event ┆ foo ┆ boo ┆ event_id │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ u32 ┆ i64 ┆ i64 ┆ i64 ┆ u32 │
╞═══════╪═══════╪═════╪═════╪══════════╡
│ 0 ┆ 0 ┆ 1 ┆ 2 ┆ null │
│ 1 ┆ 1 ┆ 2 ┆ 3 ┆ 0 │
│ 2 ┆ 1 ┆ 3 ┆ 4 ┆ 1 │
│ 3 ┆ 0 ┆ 4 ┆ 5 ┆ null │
└───────┴───────┴─────┴─────┴──────────┘
Спасибо за ответ, но что делает оператор :=?
@KevinLi Вот похожий вопрос на StackOverflow. По сути, это означает присвоение результата от df.with_row_index() к df и возврат df (чтобы впоследствии вы могли связать свои операции).
Пока решение с использованием оператора морж работает. Вероятно, более идиоматично и чисто использовать конструкцию pl.when().then() в сочетании с pl.int_range() для создания event_id.
(
df
.with_columns(
pl.when(pl.col("event") == 1)
.then(pl.int_range(pl.len()))
.over("event")
.alias("event_id")
)
)
shape: (4, 4)
┌───────┬─────┬─────┬──────────┐
│ event ┆ foo ┆ boo ┆ event_id │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═══════╪═════╪═════╪══════════╡
│ 0 ┆ 1 ┆ 2 ┆ null │
│ 1 ┆ 2 ┆ 3 ┆ 0 │
│ 1 ┆ 3 ┆ 4 ┆ 1 │
│ 0 ┆ 4 ┆ 5 ┆ null │
└───────┴─────┴─────┴──────────┘