在 Polars LazyFrame 上使用 pl.struct 时,在不同列上迭代应用 with_columns 时出现 KeyError

问题描述 投票:0回答:1

我在 with_columns 中使用 Polars 的 LazyFrame“Structs”(pl.struct) 和“apply”(又名 map_elements)时遇到以下问题

这里的想法是尝试将自定义逻辑应用于属于多个列的一组值

我已经能够使用 DataFrame 实现这一目标;但是,当切换到 LazyFrames 时,每当我尝试访问由结构发送到函数的字典中的列时,就会引发 KeyError。我逐一循环列,以便应用不同的函数(在其他地方映射到它们的名称,但在下面的示例中,为了简单起见,我将仅使用相同的函数)

  • 工作 DataFrame 实现
my_df = pl.DataFrame(
    {
        "foo": ["a", "b", "c", "d"], 
        "bar": ["w", "x", "y", "z"], 
        "notes": ["1", "2", "3", "4"]
    }
)

print(my_df)

cols_to_validate = ("foo", "bar")

def validate_stuff(value, notes):
    # Any custom logic
    if value not in ["a", "b", "x"]:
        return f"FAILED {value} - PREVIOUS ({notes})"
    else:
        return notes

for col in cols_to_validate:
    my_df = my_df.with_columns(
        pl.struct([col, "notes"]).map_elements(
            lambda row: validate_stuff(row[col], row["notes"])
        ).alias("notes")
    )

print(my_df)
  • LazyFrame 实现被破坏
my_lf = pl.DataFrame(
    {
        "foo": ["a", "b", "c", "d"], 
        "bar": ["w", "x", "y", "z"], 
        "notes": ["1", "2", "3", "4"]
    }
).lazy()

def validate_stuff(value, notes):
    # Any custom logic
    if value not in ["a", "b", "x"]:
        return f"FAILED {value} - PREVIOUS ({notes})"
    else:
        return notes

cols_to_validate = ("foo", "bar")

for col in cols_to_validate:
    my_lf = my_lf.with_columns(
        pl.struct([col, "notes"]).map_elements(
            lambda row: validate_stuff(row[col], row["notes"])
        ).alias("notes")
    )

print(my_lf.collect())

(啊,是的,请注意,单独执行每个迭代确实有效,所以对于我来说 for 循环中断的原因没有任何意义)

my_lf = my_lf.with_columns(
    pl.struct(["foo", "notes"]).map_elements(
        lambda row: validate_stuff(row["foo"], row["notes"])
    ).alias("notes")
)

my_lf = my_lf.with_columns(
    pl.struct(["bar", "notes"]).map_elements(
        lambda row: validate_stuff(row["bar"], row["notes"])
    ).alias("notes")
)

我找到了一种使用 pl.col 来实现我想要的结果的解决方法,但我想知道 Structs 是否可以像我使用 DataFrames 一样与 LazyFrames 一起使用,或者它实际上是这个 Polars 版本中的一个错误

顺便说一句,我正在使用 Polars 0.19.13。谢谢您的关注

python dataframe python-polars keyerror lazyframe
1个回答
2
投票

这更像是 Python 本身的一般“陷阱”:官方 Python 常见问题解答

它会崩溃,因为

col
最终每个
lambda

都有相同的值

一种方法是使用命名/关键字参数:

lambda row, col=col: validate_stuff(row[col], row["notes"])
shape: (4, 3)
┌─────┬─────┬───────────────────────────────────┐
│ foo ┆ bar ┆ notes                             │
│ --- ┆ --- ┆ ---                               │
│ str ┆ str ┆ str                               │
╞═════╪═════╪═══════════════════════════════════╡
│ a   ┆ w   ┆ FAILED w - PREVIOUS (1)           │
│ b   ┆ x   ┆ 2                                 │
│ c   ┆ y   ┆ FAILED y - PREVIOUS (FAILED c - … │
│ d   ┆ z   ┆ FAILED z - PREVIOUS (FAILED d - … │
└─────┴─────┴───────────────────────────────────┘
© www.soinside.com 2019 - 2024. All rights reserved.