Как объединить несколько with_columns в Polars?

Я использую Polars для преобразования своего DataFrame и хочу объединить несколько преобразований with_columns. Однако я столкнулся с проблемой при попытке выполнить операции над вновь созданным столбцом в том же контексте with_columns. В конечном итоге мне нужно сохранять DataFrame после каждого преобразования, а затем повторно применять with_columns для последующих преобразований.

Есть ли более чистый способ добиться этого?

Вот пример моего текущего подхода:

import polars as pl

# Sample data
exampledata = {
    'A': [1, 2, 3],
    'B': [4, 5, 6]
}

df = pl.DataFrame(exampledata)

# First transformation
df = df.with_columns(
    (pl.col("A") + pl.col("B")).alias("C")
)

# Second transformation
df = df.with_columns(
    (pl.col("C") * pl.col("B")).alias("D")
)

print(df)

В этом примере я создаю новый столбец C из столбцов A и B. Затем мне нужно сохранить DataFrame, прежде чем я смогу создать столбец D из C и B. Есть ли более эффективный или идиоматический способ объединить эти преобразования в Polars?

в вопросе (не в комментариях) вы должны показать, как вы это связываете и какую проблему вы получаете.

furas 06.06.2024 03:00

вы имеете в виду выполнение со многими значениями df.with_columns(X, Y) или цепочку df.with_columns(X).with_columns(Y)

furas 06.06.2024 03:04

Привет! @furas Я пытаюсь выполнить несколько преобразований столбцов, используя with_columns в Polars. Однако, если я хочу использовать вновь созданный столбец в последующей операции, мне нужно назначить DataFrame, а затем использовать новый столбец. Есть ли более эффективный способ объединить эти преобразования?

Simon 06.06.2024 03:15

для меня «изменение» означает df.with_columns(X).with_columns(Y) и это работает правильно.

furas 06.06.2024 11:10
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
4
183
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Из соображений производительности все выражения в одном контексте pl.DataFrame.with_columns оцениваются параллельно. В частности, невозможно использовать столбец, полученный из выражения в другом выражении в том же контексте.1

1 Это не означает, что поляры выполняют дублирующую работу для выражений с общими подвыражениями, поскольку под капотом используется механизм Common-Subplan-Elimination.


Тем не менее, поскольку with_columns возвращает результирующий фрейм данных, вам не нужно присваивать каждый результат обратно df, а можно напрямую связать вызовы with_columns следующим образом.

df = (
    df
    .with_columns(
        (pl.col("A") + pl.col("B")).alias("C")
    )
    .with_columns(
        (pl.col("C") * pl.col("B")).alias("D")
    )
)
shape: (3, 4)
┌─────┬─────┬─────┬─────┐
│ A   ┆ B   ┆ C   ┆ D   │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═════╪═════╪═════╪═════╡
│ 1   ┆ 4   ┆ 5   ┆ 20  │
│ 2   ┆ 5   ┆ 7   ┆ 35  │
│ 3   ┆ 6   ┆ 9   ┆ 54  │
└─────┴─────┴─────┴─────┘

Вы можете использовать оператор моржа для синтаксического получения промежуточных результатов в том же with_columns. См. stackoverflow.com/questions/76668373/…

Dean MacGregor 07.06.2024 12:12

@DeanMacGregor Лично я бы предпочел объявить c_expr = pl.col("A") + pl.col("B"), а затем использовать его дважды в одном контексте .with_columns, но, тем не менее, это интересный подход. Спасибо :)

Hericks 07.06.2024 13:06

Я имел в виду это больше для ОП. Думаю, мне следовало с самого начала отметить @Simon.

Dean MacGregor 07.06.2024 16:57

Существующий ответ верен в том смысле, что Polars, скорее всего, оптимизирует несколько вызовов with_columns, если вы находитесь в ленивом режиме (работаете на LazyFrame). Если нет, то он не будет оптимизирован.

Другой альтернативой является сохранение исходных вычислений в переменной.

a_plus_b = pl.col("A") + pl.col("B")

df.with_columns(
    a_plus_b.alias("C"),
    (a_plus_b * pl.col("B")).alias("D")
)
shape: (3, 4)
┌─────┬─────┬─────┬─────┐
│ A   ┆ B   ┆ C   ┆ D   │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═════╪═════╪═════╪═════╡
│ 1   ┆ 4   ┆ 5   ┆ 20  │
│ 2   ┆ 5   ┆ 7   ┆ 35  │
│ 3   ┆ 6   ┆ 9   ┆ 54  │
└─────┴─────┴─────┴─────┘

Дополнительная альтернатива, как указано в комментариях, — использовать оператор моржа для выполнения этого задания изнутри with_columns, как показано здесь.

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