Добавьте новый столбец с несколькими литеральными значениями в фрейм данных Polars

Рассмотрим следующий пример игрушки:

import polars as pl

pl.Config(tbl_rows=-1)

df = pl.DataFrame({"group": ["A", "A", "A", "B", "B"], "value": [1, 2, 3, 4, 5]})

print(df)

shape: (5, 2)
┌───────┬───────┐
│ group ┆ value │
│ ---   ┆ ---   │
│ str   ┆ i64   │
╞═══════╪═══════╡
│ A     ┆ 1     │
│ A     ┆ 2     │
│ A     ┆ 3     │
│ B     ┆ 4     │
│ B     ┆ 5     │
└───────┴───────┘

Далее у меня есть список значений индикатора, например vals=[10, 20, 30].

Я ищу эффективный способ вставить каждое из этих значений в новый столбец с именем ìndicator, используя pl.lit(), одновременно расширяя фрейм данных по вертикали таким образом, чтобы все существующие строки повторялись для каждого нового элемента в vals.

Мое текущее решение — вставить новый столбец в df, добавить его в список и впоследствии выполнить pl.concat.

lit_vals = [10, 20, 30]

print(pl.concat([df.with_columns(indicator=pl.lit(val)) for val in lit_vals]))

shape: (15, 3)
┌───────┬───────┬───────────┐
│ group ┆ value ┆ indicator │
│ ---   ┆ ---   ┆ ---       │
│ str   ┆ i64   ┆ i32       │
╞═══════╪═══════╪═══════════╡
│ A     ┆ 1     ┆ 10        │
│ A     ┆ 2     ┆ 10        │
│ A     ┆ 3     ┆ 10        │
│ B     ┆ 4     ┆ 10        │
│ B     ┆ 5     ┆ 10        │
│ A     ┆ 1     ┆ 20        │
│ A     ┆ 2     ┆ 20        │
│ A     ┆ 3     ┆ 20        │
│ B     ┆ 4     ┆ 20        │
│ B     ┆ 5     ┆ 20        │
│ A     ┆ 1     ┆ 30        │
│ A     ┆ 2     ┆ 30        │
│ A     ┆ 3     ┆ 30        │
│ B     ┆ 4     ┆ 30        │
│ B     ┆ 5     ┆ 30        │
└───────┴───────┴───────────┘

Поскольку df потенциально может иметь довольно много строк и столбцов, мне интересно, эффективно ли мое решение с точки зрения скорости и распределения памяти?

Просто для моего понимания: если я добавлю новый pl.DataFrame в список, будет ли этот фрейм данных использовать дополнительную память или просто будут созданы новые указатели, которые ссылаются на фрагменты памяти, содержащие данные оригинала df?

🤔 А знаете ли вы, что...
С Python можно создавать кросс-платформенные приложения для Windows, macOS и Linux.


2
50
2

Ответы:

Вы можете добавить его в виде списка, а затем взорвать():

(
    df
    .with_columns(indicator=lit_vals)
    .explode("indicator")
)

┌───────┬───────┬───────────┐
│ group ┆ value ┆ indicator │
│ ---   ┆ ---   ┆ ---       │
│ str   ┆ i64   ┆ i64       │
╞═══════╪═══════╪═══════════╡
│ A     ┆ 1     ┆ 10        │
│ A     ┆ 1     ┆ 20        │
│ A     ┆ 1     ┆ 30        │
│ A     ┆ 2     ┆ 10        │
│ A     ┆ 2     ┆ 20        │
│ A     ┆ 2     ┆ 30        │
│ A     ┆ 3     ┆ 10        │
│ A     ┆ 3     ┆ 20        │
│ A     ┆ 3     ┆ 30        │
│ B     ┆ 4     ┆ 10        │
│ B     ┆ 4     ┆ 20        │
│ B     ┆ 4     ┆ 30        │
│ B     ┆ 5     ┆ 10        │
│ B     ┆ 5     ┆ 20        │
│ B     ┆ 5     ┆ 30        │
└───────┴───────┴───────────┘

Решено

Вы можете назначить его как столбец и .explode()

df.with_columns(indicator=vals).explode("indicator")
shape: (15, 3)
┌───────┬───────┬───────────┐
│ group ┆ value ┆ indicator │
│ ---   ┆ ---   ┆ ---       │
│ str   ┆ i64   ┆ i64       │
╞═══════╪═══════╪═══════════╡
│ A     ┆ 1     ┆ 10        │
│ A     ┆ 1     ┆ 20        │
│ A     ┆ 1     ┆ 30        │
│ A     ┆ 2     ┆ 10        │
│ A     ┆ 2     ┆ 20        │
│ …     ┆ …     ┆ …         │
│ B     ┆ 4     ┆ 20        │
│ B     ┆ 4     ┆ 30        │
│ B     ┆ 5     ┆ 10        │
│ B     ┆ 5     ┆ 20        │
│ B     ┆ 5     ┆ 30        │
└───────┴───────┴───────────┘

Чтобы указать dtype, вы можете использовать pl.lit()

(df.with_columns(indicator=pl.lit(vals, dtype=pl.List(pl.UInt8)))
   .explode("indicator")
)
shape: (15, 3)
┌───────┬───────┬───────────┐
│ group ┆ value ┆ indicator │
│ ---   ┆ ---   ┆ ---       │
│ str   ┆ i64   ┆ u8        │
╞═══════╪═══════╪═══════════╡
│ A     ┆ 1     ┆ 10        │
│ A     ┆ 1     ┆ 20        │
│ A     ┆ 1     ┆ 30        │
│ A     ┆ 2     ┆ 10        │
│ A     ┆ 2     ┆ 20        │
│ …     ┆ …     ┆ …         │
│ B     ┆ 4     ┆ 20        │
│ B     ┆ 4     ┆ 30        │
│ B     ┆ 5     ┆ 10        │
│ B     ┆ 5     ┆ 20        │
│ B     ┆ 5     ┆ 30        │
└───────┴───────┴───────────┘