Добавьте новый столбец с несколькими литеральными значениями в фрейм данных 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 есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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        │
└───────┴───────┴───────────┘

Можно ли напрямую привести элементы vals к pl.Uint8?

Andi 06.09.2024 11:19

Вы имеете в виду лайк indicator=pl.lit(vals, dtype=pl.List(pl.UInt8))?

jqurious 06.09.2024 11:29

Да, dtype отдельных элементов vals должен быть pl.Uint8. Его можно использовать после explode. Мне просто интересно, смогу ли я сделать это при назначении нового столбца?

Andi 06.09.2024 11:35
df.with_columns(indicator=pl.lit(vals, dtype=pl.List(pl.UInt8))).explode(...) должен это сделать.
jqurious 06.09.2024 11:37

Вы правы! Спасибо

Andi 06.09.2024 11:42

Другие вопросы по теме